When working in Interface Builder, you are able to modify attributes for the views that you add to the canvas. For example, you can set the background color on a view, the text on a label, and the current progress on a slider. You can add this same behavior to your own custom UIView subclasses for certain types. Let’s add in the ability for the DrawView’s current line color, finished line color, and line thickness to be customized through Interface Builder.
In DrawView.swift, declare three properties to reference these values. Give them default values and have the view flag itself for redrawing whenever these properties change.
var currentLines = [NSValue:Line]() var finishedLines = [Line]() @IBInspectable var finishedLineColor: UIColor = UIColor.black { didSet { setNeedsDisplay() } } @IBInspectable var currentLineColor: UIColor = UIColor.red { didSet { setNeedsDisplay() } } @IBInspectable var lineThickness: CGFloat = 10 { didSet { setNeedsDisplay() } }
The @IBInspectable
keyword lets Interface Builder know that this is a property that you want to customize through the attributes inspector. Many of the common types are supported by @IBInspectable
: Booleans, strings, numbers, CGPoint, CGSize, CGRect, UIColor, UIImage, and a few more are all candidates.
Now update stroke(_:) and drawView(_:) to use these new properties.
func stroke(_ line: Line) { let path = UIBezierPath()path.lineWidth = 10path.lineWidth = lineThickness path.lineCapStyle = .round path.move(to: line.begin) path.addLine(to: line.end) path.stroke() } override func draw(_ rect: CGRect) {// Draw finished lines in blackUIColor.black.setStroke()finishedLineColor.setStroke() for line in finishedLines { stroke(line) }// Draw current lines in redUIColor.red.setStroke()currentLineColor.setStroke() for (_, line) in currentLines { stroke(line) } }
Now, when you add a DrawView to the canvas in Interface Builder, you can customize these three properties in the attributes inspector to be different for different instances (Figure 18.7).