相对于 UIButton 框架的 drawRect 框架不正确
Incorrect drawRect frame relative to UIButton frame
我正在尝试向某些 UIButton 添加状态指示器,将其直接插入以下屏幕截图中蓝色指示器所在的位置。我首先通过使用 minY 和 minX 从头开始创建第一行指标代码来使用 UIButton 原点作为参考点来进行校准,然后将其复制到其他两个指标,认为它应该翻译,但似乎没有。
//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).
这是我绘制每个指标的方式,圆圈颜色填充代码行是 DrawBlueCircle、DrawYellowCircle 和 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)
}
}
然而不幸的是,只有蓝色指示器被正确绘制。
在我尝试调试的过程中,我将每一步都打印到控制台,如下面的代码所示,但是代码和屏幕不匹配。
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)
控制台输出:
(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)
通过继承 UIView
并添加一个按钮,可以更轻松地完成此操作。只需将指标添加为子视图即可。在 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)
}
}
像这样使用它:
let b = IndicatorButton(frame: CGRectMake(0,0,100,30))
b.indicatorColor = UIColor.redColor()
b.button.setTitle("Start", forState: .Normal)
b
结果:
我正在尝试向某些 UIButton 添加状态指示器,将其直接插入以下屏幕截图中蓝色指示器所在的位置。我首先通过使用 minY 和 minX 从头开始创建第一行指标代码来使用 UIButton 原点作为参考点来进行校准,然后将其复制到其他两个指标,认为它应该翻译,但似乎没有。
//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).
这是我绘制每个指标的方式,圆圈颜色填充代码行是 DrawBlueCircle、DrawYellowCircle 和 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)
}
}
然而不幸的是,只有蓝色指示器被正确绘制。
在我尝试调试的过程中,我将每一步都打印到控制台,如下面的代码所示,但是代码和屏幕不匹配。
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)
控制台输出:
(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)
通过继承 UIView
并添加一个按钮,可以更轻松地完成此操作。只需将指标添加为子视图即可。在 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)
}
}
像这样使用它:
let b = IndicatorButton(frame: CGRectMake(0,0,100,30))
b.indicatorColor = UIColor.redColor()
b.button.setTitle("Start", forState: .Normal)
b
结果: