UIButton that resizes to fit its titleLabel

前端 未结 12 1281
既然无缘
既然无缘 2020-12-01 09:13

I have a UIButton that I add to my view controller\'s view in a storyboard. I add centering constraints to position it and leading space constraints to limit it

相关标签:
12条回答
  • 2020-12-01 09:29

    Override the -(CGSize)intrinsicContentSize in Custom UIButton as given below.

    Objective - C:

    -(CGSize)intrinsicContentSize {
        CGSize titleLabelIntrinsicSize = [self.titleLabel intrinsicContentSize];
        return CGSizeMake(titleLabelIntrinsicSize.width + self.contentEdgeInsets.left + self.contentEdgeInsets.right, titleLabelIntrinsicSize.height + self.contentEdgeInsets.top + self.contentEdgeInsets.bottom);
    }
    

    Swfit :

    override var intrinsicContentSize: CGSize {
            get {
                if let thisSize = self.titleLabel?.intrinsicContentSize {
                    return CGSize(width: thisSize.width + self.contentEdgeInsets.left + self.contentEdgeInsets.right, height: thisSize.height + self.contentEdgeInsets.top + self.contentEdgeInsets.bottom)
                }
                return super.intrinsicContentSize
            }
        }
    
    0 讨论(0)
  • 2020-12-01 09:33

    Got same issue. It happens only if UIButton's titleLabel has more than one line. Is it a bug in UIKit?

    My Swift solution:

    class ResizableButton: UIButton {    
        override var intrinsicContentSize: CGSize {
            let labelSize = titleLabel?.sizeThatFits(CGSize(width: frame.size.width, height: CGFloat.greatestFiniteMagnitude)) ?? .zero
            let desiredButtonSize = CGSize(width: labelSize.width + titleEdgeInsets.left + titleEdgeInsets.right, height: labelSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom)
    
            return desiredButtonSize
        }
    }
    
    0 讨论(0)
  • 2020-12-01 09:34

    I am away from my computer so I can't add the code right now, but I have found a workaround of this before.

    What you can do is create a UILabel and add a UITapGestureRecognizer to the label. Do whatever you want for the button's action by handling the tap event. And also make sure that you enable user interactions on the UILabel.

    This label will now behave as a auto resizing button.

    0 讨论(0)
  • 2020-12-01 09:34

    I had to invalidate the intrinsic content size when the views were laid out and then calculate the height of the button for the intrinsicContentSize property.

    Here's the code in Swift3/Xcode 9

    override func layoutSubviews() {
        self.invalidateIntrinsicContentSize()
        super.layoutSubviews()
    }
    
    
    override var intrinsicContentSize: CGSize {
        return CGSize(width: self.frame.size.width, height: titleLabel!.frame.size.height + contentEdgeInsets.top + contentEdgeInsets.bottom)
    }
    
    0 讨论(0)
  • 2020-12-01 09:35

    I struggled with this for a while and ended up making it work by subclassing UIButton and adding these two functions

    class GoalsButton: UIButton {
    
        override var intrinsicContentSize: CGSize {
            return self.titleLabel!.intrinsicContentSize
        }
    
        // Whever the button is changed or needs to layout subviews,
        override func layoutSubviews() {
            super.layoutSubviews()
            titleLabel?.preferredMaxLayoutWidth = self.titleLabel!.frame.size.width
        }
    }
    
    0 讨论(0)
  • 2020-12-01 09:40

    [self.button sizeToFit] should work if your Autolayout is turned Off. If you have to use autolayout then other suggestions (calculating line width) etc are more appropriate.

    0 讨论(0)
提交回复
热议问题