工程日记之HelloSlide(1):Swift自定义可视化组件的方法(继承UIView和在StoryBoard中设置)

时间:2024-05-04 23:04:55

需求描述

HelloSlide是把文本自动转化成幻灯片的软件,在幻灯片中我们有SmartArt:各种各样的几何形状,并且可以自定义大小和颜色,放在幻灯片不同的位置。

为了在我们的软件中实现类似的效果,我封装了一些自定义的组件,因为暂时只需要几何形状,我通过直接继承UIView来实现

代码

class ArcView:UIView{
var mystrokecolor:UIColor //设置笔触颜色
var color : UIColor //设置填充颜色
init(frame:CGRect,color:UIColor,strokecolor:UIColor){
self.mystrokecolor = strokecolor
self.color = color
super.init(frame:frame)
self.backgroundColor = UIColor.clear //要将背景色设置为透明 }
required init(coder acoder:NSCoder) {
fatalError("some error in Xcode")
} override func draw(_ rect: CGRect){
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else{
return
}
let path = CGMutablePath()
path.move(to: CGPoint(x:self.bounds.minX,y:self.bounds.minY)) //设置起点
path.addLine(to: CGPoint(x:self.bounds.maxX,y:self.bounds.minY))
path.addLine(to: CGPoint(x:self.bounds.maxX,y:self.bounds.maxY))
path.addLine(to: CGPoint(x:self.bounds.minX,y:self.bounds.maxY))
path.addLine(to: CGPoint(x:self.bounds.minX,y:self.bounds.minY))
     //完成path的绘制
//path.addRect(T##rect: CGRect##CGRect) context.addPath(path)      // 设置笔触样式
context.setStrokeColor(mystrokecolor.cgColor)
context.setLineWidth()
context.setFillColor(color.cgColor)
context.strokePath()
} }

解释

1 用的Core Graphics框架。Core Graphics提供CGMutablePath的底层API,而UIBezierPath事实上是对CGMutablePath的封装

2 我们使用的 UIKit 库中所有 UI 组件其实都是由 CoreGraphics 绘制实现的。所以使用 Core Graphics 可以实现比 UIKit 更底层的功能。

3 我们开放了两个属性:笔触颜色和填充颜色,用来自定义颜色;其他的如空间大小等可以直接继承自UIView中的属性

深度需求探索

如果我们希望把这个组件放到Storyboard上面,需要做一点调整

@IBDesignable:用来标识自定义组件类,这样在StoryBoard中就能能实时更新视图。
@IBInspectable:用来标识属性,这样在Attribute Inspector(属性检查器)中查看设置该属性。

代码

class ArcView:UIView{
var mystrokecolor:UIColor
//设置笔触颜色
var color : UIColor //设置填充颜色
init(frame:CGRect,color:UIColor,strokecolor:UIColor){
self.mystrokecolor = strokecolor
self.color = color
super.init(frame:frame)
self.backgroundColor = UIColor.clear //要将背景色设置为透明 }
required init(coder acoder:NSCoder) {
fatalError("some error in Xcode")
} override func draw(_ rect: CGRect){
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else{
return
}
let path = CGMutablePath()
path.move(to: CGPoint(x:self.bounds.minX,y:self.bounds.minY)) //设置起点
path.addLine(to: CGPoint(x:self.bounds.maxX,y:self.bounds.minY))
path.addLine(to: CGPoint(x:self.bounds.maxX,y:self.bounds.maxY))
path.addLine(to: CGPoint(x:self.bounds.minX,y:self.bounds.maxY))
path.addLine(to: CGPoint(x:self.bounds.minX,y:self.bounds.minY))
     //完成path的绘制
//path.addRect(T##rect: CGRect##CGRect) context.addPath(path)      // 设置笔触样式
context.setStrokeColor(mystrokecolor.cgColor)
context.setLineWidth()
context.setFillColor(color.cgColor)
context.strokePath()
} } // 把上述这个view放到一个IBDesignable类型的class中去
@IBDesignable class myview : UIView{
private var thisview : ArcView()
@IBInspectable var strokecolor : UIColor = .white{

  didSet{

    self.thisview.strokeColor = strokecolor;

  }

}

另外

但是如果组件里的元素比较多,布局比较复杂。那用纯代码写就比较麻烦了。对于这种复杂的自定义组件,我们可以结合 XIB 文件来实现。
使用XIB的方式可以省去initWithFrame:layoutSubviews中添加子控件和设置子控件尺寸的步骤,还有在view controller里面设置view的frame,因为添加子控件和设置子控件的尺寸以及整个view的尺寸在xib中就已经完成。(注意整个view的位置还没有设置,需要在controller里面设置。)

参考:https://www.hangge.com/blog/cache/detail_1394.html

https://www.jianshu.com/p/7e47da62899c