Autolayout - intrinsic size of UIButton does not include title insets

前端 未结 12 1071
不知归路
不知归路 2020-12-07 07:11

If I have a UIButton arranged using autolayout, its size adjusts nicely to fit its content.

If I set an image as button.image, the instrinsic size again

相关标签:
12条回答
  • 2020-12-07 08:03

    Why not override the intrinsicContentSize method on UIView? For example:

    - (CGSize) intrinsicContentSize
    {
        CGSize s = [super intrinsicContentSize];
    
        return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right,
                          s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom);
    }
    

    This should tell the autolayout system that it should increase the size of the button to allow for the insets and show the full text. I'm not at my own computer, so I haven't tested this.

    0 讨论(0)
  • 2020-12-07 08:04

    You can get this to work in Interface Builder (without writing any code), by using a combination of negative and positive Title and Content Insets.

    enter image description here

    Update: Xcode 7 has a bug where you cannot enter negative values in the Right Inset field, but you can use the stepper control next to it to decrease the value. (Thanks Stuart)

    Doing this will add 8pt of spacing between the image and the title and will increase the intrinsic width of the button by the same amount. Like this:

    enter image description here

    0 讨论(0)
  • 2020-12-07 08:06

    For Swift 3 based on pegpeg's answer:

    extension UIButton {
    
        override open var intrinsicContentSize: CGSize {
    
            let intrinsicContentSize = super.intrinsicContentSize
    
            let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
            let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom
    
            return CGSize(width: adjustedWidth, height: adjustedHeight)
    
        }
    
    }
    
    0 讨论(0)
  • 2020-12-07 08:11

    You haven't specified how you're setting the insets, so I'm guessing that you're using titleEdgeInsets because I see the same effect you're getting. If I use contentEdgeInsets instead it works properly.

    - (IBAction)ChangeTitle:(UIButton *)sender {
        self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
        [self.button setTitle:@"Long Long Title" forState:UIControlStateNormal];
    }
    
    0 讨论(0)
  • 2020-12-07 08:11

    The option is also available in interface builder. See the Inset. I set left and right to 3. Works like a charm.

    Interface builder screenshot

    0 讨论(0)
  • 2020-12-07 08:11

    calling sizeToFit() makes sure that contentEdgeInset is taken into effect

    extension UIButton {
    
       open override func draw(_ rect: CGRect) { 
           self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 40, bottom: 10, right: 40)
           self.sizeToFit()
       }
    }
    
    0 讨论(0)
提交回复
热议问题