I am attempting to add status indicators to some UIButtons, nuzzling it right into the spot the blue indicator is in the following screenshot. I first calibrated by creating the first indicator line of code from scratch using minY and minX to use the UIButton origin as a reference point, then copied it for the other two indicators thinking it should translate but it seems it has not.
//In header/property declaration
@IBOutlet weak var thirdButton: UIButton!
@IBOutlet weak var secondButton: UIButton!
@IBOutlet weak var firstButton: UIButton!
var capicheIndicator: UIView!
var secondIndicator: UIView!
var thirdIndicator: UIView!
// In viewDidLoad
let firstButtonFrame = firstButton.frame
self.capicheIndicator = DrawBlueCircle(frame: CGRect(x: firstButtonFrame.minX + 15, y: firstButtonFrame.minY + 4, width: 11, height: 11))
self.view.addSubview(capicheIndicator)
let secondButtonFrame = secondButton.frame
self.secondIndicator = DrawYellowCircle(frame: CGRect(x: secondButtonFrame.minX + 15, y: secondButtonFrame.minY + 4, width: 11, height: 11))
self.view.addSubview(secondIndicator)
let thirdButtonFrame = thirdButton.frame
self.thirdIndicator = DrawRedCircle(frame: CGRect(x: thirdButtonFrame.minX + 15, y: thirdButtonFrame.minY + 4, width: 11, height: 11))
self.view.addSubview(thirdIndicator).
This is how I draw each indicator, with the circle color fill line of code being the only change between DrawBlueCircle, DrawYellowCircle, and DrawRedCircle.
class DrawBlueCircle: UIView {
override func drawRect(rect: CGRect)
{
let contextRef = UIGraphicsGetCurrentContext()
CGContextClearRect(contextRef, rect)
//Set the border width
CGContextSetLineWidth(contextRef, 1.5)
//Set the circle fil
CGContextSetRGBFillColor(contextRef, 0/255, 122/255, 1, 1)
CGContextFillEllipseInRect(contextRef, rect)
}
}
However unfortunately, only the blue indicator is getting drawn correctly.
In my attempts to debug I printed to the console every step of the way as shown by the following code, but the code and the screen somehow do not match.
let firstButtonFrame = firstButton.frame
print(firstButtonFrame)
print(firstButtonFrame.minY)
self.capicheIndicator = DrawBlueCircle(frame: CGRect(x: firstButtonFrame.minX + 15, y: firstButtonFrame.minY + 4, width: 11, height: 11))
print(capicheIndicator.frame)
self.view.addSubview(capicheIndicator)
let secondButtonFrame = secondButton.frame
print(secondButtonFrame)
print(secondButtonFrame.minY)
self.secondIndicator = DrawYellowCircle(frame: CGRect(x: secondButtonFrame.minX + 15, y: secondButtonFrame.minY + 4, width: 11, height: 11))
print(secondIndicator.frame)
self.view.addSubview(secondIndicator)
let thirdButtonFrame = thirdButton.frame
print(thirdButtonFrame)
print(thirdButtonFrame.minY)
self.thirdIndicator = DrawRedCircle(frame: CGRect(x: thirdButtonFrame.minX + 15, y: thirdButtonFrame.minY + 4, width: 11, height: 11))
print(thirdIndicator.frame)
self.view.addSubview(thirdIndicator)
And the console output:
(36.0, 381.0, 528.0, 40.0)
381.0
(51.0, 385.0, 11.0, 11.0)
(36.0, 431.0, 528.0, 40.0)
431.0
(51.0, 435.0, 11.0, 11.0)
(36.0, 481.0, 528.0, 40.0)
481.0
(51.0, 485.0, 11.0, 11.0)
This is done so much more easily by subclassing UIView
and adding a button. Just add the indicator as a subview. Try this in Playground:
class IndicatorButton: UIView {
let indicatorView: UIView = {
let indicator = UIView(frame: CGRectMake(0,0,10,10))
indicator.layer.cornerRadius = 5.0
indicator.clipsToBounds = true
indicator.backgroundColor = UIColor.clearColor()
return indicator
}()
var indicatorColor: UIColor = UIColor.clearColor() {
didSet {
indicatorView.backgroundColor = indicatorColor
self.layer.borderColor = indicatorColor.CGColor
self.button.setTitleColor(indicatorColor, forState: .Normal)
}
}
let button: UIButton = {
let button = UIButton(type: .Custom)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.borderWidth = 2.0
self.layer.borderColor = indicatorColor.CGColor
self.layer.cornerRadius = 8.0
self.clipsToBounds = true
button.frame = CGRectMake(0, 0, frame.size.width, frame.size.height)
button.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
button.titleEdgeInsets = UIEdgeInsetsMake(0,15,0,0)
self.addSubview(button)
self.addSubview(indicatorView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
indicatorView.frame = CGRectMake(10, (self.bounds.size.height-10) / 2.0, 10,10)
}
}
Use it like this:
let b = IndicatorButton(frame: CGRectMake(0,0,100,30))
b.indicatorColor = UIColor.redColor()
b.button.setTitle("Start", forState: .Normal)
b
Result: