【问题标题】:Incorrect drawRect frame relative to UIButton frame相对于 UIButton 框架的 drawRect 框架不正确
【发布时间】:2015-11-21 23:21:41
【问题描述】:

我正在尝试向一些 UIButtons 添加状态指示符,将它按到下面屏幕截图中蓝色指示符所在的位置。我首先通过使用 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)

【问题讨论】:

  • 为什么这被否决了?请提供解释,作为学习机会,本网站的目的。

标签: ios swift uibutton frame cgrect


【解决方案1】:

通过继承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

结果:

【讨论】:

  • 知道如果我在情节提要中制作 UIView 并通过 IBOutlets 链接它们,为什么会触发 fatalError 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多