【问题标题】:UIButton align image left and center textUIButton 将图像左对齐和居中文本
【发布时间】:2019-02-03 16:42:56
【问题描述】:

简介:

我有一个类,它继承来自UIButton。在这个类中,我想更新属性,比如titleEdgeInsetsimageEdgeInsetscontentHorizontalAlignment

我的第一个方法是使用layoutSubviews

override func layoutSubviews() {
    super.layoutSubviews()

    // update properties 
}

layoutSubviews 创建了一个无限循环,因此我已经搜索了另一种方法。

我的问题:

使用willMove 方法更新 UIButton 属性是一种常见的方式吗?

override func willMove(toWindow newWindow: UIWindow?) {
    super.willMove(toWindow: newWindow)

    // update properties
}

如果不是,为什么?

我的目标是让按钮的 imageView 左对齐(带填充)并使文本居中。

更新:

我需要按钮 frame.size 和 bounds.width 来计算文本和图像视图的位置

【问题讨论】:

    标签: ios swift xcode uibutton layoutsubviews


    【解决方案1】:

    您上面提到的所有属性都可以在UIButtoninit 中设置,绝对不需要在layoutSubviewswillMove(toWindow 中设置它们。 layoutSubviews 将被多次调用,因此在这里再次设置这些属性是没有意义的。 willMove(toWindow 将在按钮添加到某些视图并加载按钮时被调用,但您不必等到那时设置这些属性。因为你已经有一个按钮的子类,所以我建议你这样做

    class SomeButton: UIButton {
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            self.contentHorizontalAlignment = .center
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    

    顺便说一句,不建议创建UIButton 的子类,因此如果您只想将这些属性分配给您的按钮,您可以将扩展名添加到UIButton

    extension UIButton {
        func applyStyle() {
            self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            self.contentHorizontalAlignment = .center
        }
    }
    

    编辑:

    这是你想要的吗??

    无论文本是什么,文本始终位于中心,图像在其左侧,内边距为 10 像素

    编辑 2:

    正如 OP 确认的那样,他希望按钮的样式如上图所示,并发布代码以实现相同的效果

    class SomeButton: UIButton {
        var titleFont: UIFont! = nil
        var textSize: CGFloat = 0
        let imageWidth: CGFloat = 20
        let buttonHeight: CGFloat = 30
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.titleFont = titleLabel!.font
            self.setTitle("here", for: .normal)
            self.setTitleColor(UIColor.red, for: .normal)
            self.setImage(UIImage(named: "hand"), for: .normal)
            self.backgroundColor = UIColor.green
        }
    
        override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
            if let string = self.title(for: .normal) {
                textSize = string.widthOfString(usingFont: self.titleFont)
                //30 because imageWidth + 10 padding
                return CGRect(origin: CGPoint(x: 30, y: 0), size: CGSize(width: textSize + 30, height: buttonHeight))
            }
            return CGRect.zero
        }
    
        override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
            return CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: imageWidth, height: buttonHeight))
        }
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        override var intrinsicContentSize: CGSize {
            //60 because you need eauql padding on both side 30 + 30 = 60
            return CGSize(width: textSize + 60, height: buttonHeight)
        }
    }
    
    extension String {
    
        func widthOfString(usingFont font: UIFont) -> CGFloat {
            let fontAttributes = [NSAttributedString.Key.font: font]
            let size = self.size(withAttributes: fontAttributes)
            return size.width
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 它不起作用,因为我需要框架大小和边界宽度来计算按钮图像视图和按钮文本的位置。抱歉,我已经更新了我的问题..
    • @sean-stayn 你可以通过让 width = self.bounds.width 来访问宽度和高度,让 height = self.bounds.height 让我知道我是否没有让你正确
    • @sean-stayn :您是否打算根据按钮内容应用动态插图?这就是为什么你想这样做willMove(toWindow?虽然使用willMove(toWindow 并不是一种非常有效的方法
    • 是的,你是对的!这是必要的,因为我想将按钮文本居中并使用填充将图像向左对齐。
    • @sean-stayn 如果您的要求只是将文本居中对齐并将图像放置在其左侧并使用固定填充,您不需要知道之前的宽度,请稍等一下让我更新我的答案。如果您可以更新所需按钮样式的照片/图像,将会很有帮助
    猜你喜欢
    • 2012-06-12
    • 1970-01-01
    • 2015-03-03
    • 2019-10-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    相关资源
    最近更新 更多