Swift iOS - 如何排列子图层位置以匹配按钮文本的中心

时间:2018-05-29 17:37:51

标签: ios swift calayer centering

我有一个文本按钮。我添加了一个红色背景subLayer,我使backgroundLayer的宽度和高度大于按钮文本。我尝试使用以下方法将背景图层置于按钮中心:

backgroundLayer.position = button.center

它不是居中的。这就是我得到的:

enter image description here

我知道我可以直接在按钮上设置背景颜色和cornerRadius但是当我这样做时,红色背景会拥抱文本:

button.backgroundColor = UIColor.red
button.layer.cornerRadius = 10

enter image description here

我希望redbackground比文本更宽更高:

backgroundLayer.frame = CGRect(x: 0, y: 0, width: buttonTextSize.width + 10, height: buttonTextSize.height + 5

我会以Photoshop为例,但目前我还没有Photshop在我面前。这是我能找到的最接近的。这是Vimeo的按钮。他们没有使用文本,但backgroundLayer比按钮图像更宽更高,而backgroundLayer的位置与按钮的midX和midY对齐:

enter image description here

如何让背景subLayer的位置与按钮文本的中心对齐?

let button: UIButton = {
    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("Next", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.contentHorizontalAlignment = .center
    button.titleLabel?.font = UIFont.systemFont(ofSize: 23)
    return button
}()

let backgroundLayer: CALayer = {
    let layer = CALayer()
    layer.backgroundColor = UIColor.red.cgColor
    layer.cornerRadius = 10
    return layer
}()

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = UIColor.lightGray

    view.addSubview(button)
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let buttonText = button.titleLabel?.text
    let buttonTextSize = (buttonText! as NSString).size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 23.0)])

    // I added 10 points to the backgroundLayer's width and 5 points to the backgroundLayer's height so its wider then the text
    backgroundLayer.frame = CGRect(x: 0, y: 0, width: buttonTextSize.width + 10, height: buttonTextSize.height + 5)
    button.layer.insertSublayer(backgroundLayer, at: 0)

    backgroundLayer.position = button.center
}

2 个答案:

答案 0 :(得分:2)

这里有一个看起来像你想要的按钮(当然你可以调整任何不适合你敏感度的参数):

enter image description here

此按钮自动为红色,圆角,并且比文本大得多(即使按钮定位使用自动布局)。

以下是通过子类实现的方式:

class MyRedButton : UIButton {
    override func layoutSubviews() {
        super.layoutSubviews()
        self.backgroundColor = .red
        self.layer.cornerRadius = 10
    }
    override var intrinsicContentSize: CGSize {
        var sz = super.intrinsicContentSize
        sz.width += 30; sz.height += 30
        return sz
    }
}

答案 1 :(得分:1)

马特的赞成回答是正确的。

他在我最初做错的评论中向我指出的两件事是。

  1. 我尝试设置backgroundLayer.position = button.center。这是错误的,因为按钮的中心基于框架的中心,而不是界限中心。我应该设置backgroundLayer.position以匹配按钮边界的中心
  2. 我试图将backgroundLayer的位置设置为viewWillLayoutSubviews中按钮的中心,他说按钮的界限还不知道,所以backgroundLayer没有信息可以根据它。我应该将代码添加到viewDidLayoutSubviews
  3. 这是以下代码:

    // 1. add the code to viewDidLayoutSubviews
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        let text = button.titleLabel?.text
        let textSize = (text! as NSString).size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 23.0)])
    
        backgroundLayer.frame = CGRect(x: 0, y: 0, width: textSize.width + 10, height: textSize.height + 5)
        button.layer.insertSublayer(backgroundLayer, at: 0)
    
        // 2. get the buttons bound's center by accessing it's midX and midY
        let buttonMidX = button.bounds.midX
        let buttonMidY = button.bounds.midY
        let buttonBoundsCenter = CGPoint(x: buttonMidX, y: buttonMidY)
    
        // 3. set the backgroundLayer's postion to the buttonBoundsCenter
        backgroundLayer.position = buttonBoundsCenter
    }
    

    它有效:

    enter image description here