使用自动布局将子视图添加到 UIButton 上

4

我创建了一个UIButton的子类。这个子类(BubbleBtn)负责向按钮添加一个UIView

被添加的视图应该距离父按钮顶部、左侧和右侧6个点,同时占用父按钮高度的一半。

代码:

class BubbleBtn: UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        addBubbleView()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addBubbleView()
    }
    func addBubbleView() {
        setNeedsLayout()
        layoutIfNeeded()
        let bubbleBuffer:CGFloat = 6
        let bubble = UIView(frame: CGRect(x: bubbleBuffer, y: bubbleBuffer, width: self.frame.width - (bubbleBuffer * 2), height: (self.frame.height / 2)))
        bubble.isUserInteractionEnabled = false
        bubble.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
        bubble.layer.cornerRadius = 10
        bubble.layer.zPosition = -1
        self.addSubview(bubble)
    }
}

问题在于添加的UIView的宽度和高度不是正确的大小;对于较大的按钮,宽度和高度都太短了。
我该如何将UIView添加到按钮上,以便气泡视图以正确的大小呈现?
下面是发布的屏幕截图: Autolayout problem with subclass button

添加 bubble.frame = self.bounds。 - Anbu.Karthik
2个回答

2
尝试为按钮内的视图添加约束。
func addBubbleView() {
   let bubble = UIView()
    bubble.isUserInteractionEnabled = false
    bubble.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
    bubble.layer.cornerRadius = 10
    bubble.layer.zPosition = -1
    self.addSubview(bubble)
    bubble.translatesAutoresizingMaskIntoConstraints = false
    let views = [
        "bubble": bubble
    ]
    var constraints = [NSLayoutConstraint]()
    let vBtnConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-6-[bubble]-6-|", options: .init(rawValue: 0), metrics: nil, views: views)
    let hBtnConstraint = NSLayoutConstraint.constraints(withVisualFormat: "H:|-6-[bubble]-6-|", options: .init(rawValue: 0), metrics: nil, views: views)
    constraints += vBtnConstraint
    constraints += hBtnConstraint
    NSLayoutConstraint.activate(constraints)
}

我喜欢使用VFL的想法。然而,vBtnConstraint的声明,有没有办法使垂直约束的宽度成为按钮高度的“一半”的动态宽度? - Joe
我认为你想让气泡居中并且高度等于按钮高度的一半。请使用以下代码替换vBtnContraint:let vBtnConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(self.frame.height/4)-[bubble]-(self.frame.height/4)-|", options: .init(rawValue: 0), metrics: nil, views: views) - KiranMayee Maddi
这导致应用程序崩溃:libc++abi.dylib:以未捕获的NSException类型终止(lldb) - Joe
糟糕..添加这个: let vBtnConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(self.frame.height/4)-[bubble]-\(self.frame.height/4)-|", options: .init(rawValue: 0), metrics: nil, views: views) 在之前的代码中漏掉了一个斜杠 - KiranMayee Maddi
啊哈!VFL 中的字符串内插。我稍微修改了你的代码为:"V:|-6-[bubble]-(self.frame.height/2)-|" - 它有点起作用,但是,行 'self.frame.height/2' 仍然没有产生正确的值。我不知道我的约束或自动布局是否有问题。我只想让气泡在距离顶部 6 的地方开始,并以按钮高度的一半结束。将会继续努力。 - Joe
你可以在括号中给出气泡的高度。试试这个:let vBtnConstraint = NSLayoutConstraint.constraints(withVisualFormat: "V:|-6-[bubble(\(self.frame.height/2))]", options: .init(rawValue: 0), metrics: nil, views: views) 希望这能帮到你 :) - KiranMayee Maddi

1

您应该根据父视图的bounds和正确的autoresizingMask来设置框架。

let bubble = UIView(frame: CGRect(x: bubbleBuffer, y: bubbleBuffer,
    width: self.bounds.width - (bubbleBuffer * 2), 
    height: self.bounds.height - (2 * bubbleBuffer))
bubble.translatesAutoresizingMaskIntoConstraints = true
bubble.autoresizingMask = [ .flexibleWidth, .flexibleHeight ]

所以当父视图的框架改变时,bubble会适应其宽度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接