如何在 iOS7 中使用自动布局让按钮垂直增长?

Posted

技术标签:

【中文标题】如何在 iOS7 中使用自动布局让按钮垂直增长?【英文标题】:How to get a button to grow vertically using Auto Layout in iOS7? 【发布时间】:2013-12-03 19:54:29 【问题描述】:

使用 IB 和自动布局我想要一个按钮,当标题很长时,它的大小会垂直增长。

我为按钮添加了顶部、前导和尾部约束以及自动换行的换行符。然后我在 viewDidLoad 中分配了一个长标题。但生成的按钮不适合内容。我在这里错过了什么?

试图克服高度自动更新的不足:

CGFloat width = 280;
NSAttributedString *attributedText =
[[NSAttributedString alloc]
 initWithString:self.button.titleLabel.text
 attributes:@
 NSFontAttributeName: self.button.titleLabel.font];
CGRect rect = [attributedText boundingRectWithSize:(CGSize)width, CGFLOAT_MAX
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;
CGRect buttonRect = self.button.frame;
buttonRect.size.height = size.height;
[self.button setFrame: buttonRect];

但是按钮的框架没有更新.....

通过下面rdelmar提供的出色解决方案,我得到了以下结果:

【问题讨论】:

这些限制对我有用。你确定没有其他限制吗? 是的 - 这是唯一的限制。如果我添加背景按钮不会增长。文本是可见的 - 但不在按钮的边界内。你也这么看吗? 【参考方案1】:

如果你想把标题放在图片上(不是在旁边),你需要使用 backgroundImage:forState:。据我通过实验得知,您无法以自动方式使图像随标题扩展。如果您没有图像,那么这些约束会使标题垂直扩展。

编辑后:我从来没有找到任何好的自动方法来做到这一点,但你可以通过计算字符串的高度,并相应地调整按钮的高度来做到这一点。我发现最好的方法是在 IB 中为按钮提供宽度和高度约束——这将导致您的背景图像拉伸或收缩以适应该框架。我创建了一个 UIButton 子类(更改了 IB 中按钮的类),并将这段代码放入其中:

@interface RDButton ()
@property (strong,nonatomic) NSLayoutConstraint *hCon;
@property (strong,nonatomic) NSLayoutConstraint *wCon;
@property (nonatomic) CGFloat startingHeight;
@end

@implementation RDButton

-(id)initWithCoder:(NSCoder *)aDecoder 
    if (self = [super initWithCoder:aDecoder]) 
        for (NSLayoutConstraint *con in self.constraints) 
            if (con.firstAttribute == NSLayoutAttributeHeight) 
                self.hCon = con;
                self.startingHeight = con.constant;
            else if (con.firstAttribute == NSLayoutAttributeWidth)
                self.wCon = con;
            
        
    
    self.titleLabel.numberOfLines = 0;
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
    return self;


-(void)setTitle:(NSString *)title forState:(UIControlState)state 
    [super setTitle:title forState:state];
    NSStringDrawingContext *ctx = [NSStringDrawingContext new];
    CGSize s = [title boundingRectWithSize:CGSizeMake(self.wCon.constant, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@NSFontAttributeName:self.titleLabel.font context:ctx].size;
    self.hCon.constant = fmax (s.height, self.startingHeight - 5) + 5; // the +5 gives about the same padding as the original button.

在我设置新标题的视图控制器中,我有这个:

- (void)viewDidLoad 
    [super viewDidLoad];
    [self.button setTitle:@"A long long long Title" forState:UIControlStateNormal];
    UIImage *img = [UIImage imageNamed:@"pic.jpg"];
    [self.button setBackgroundImage:img forState:UIControlStateNormal];

【讨论】:

我一定遗漏了一些非常基本的东西。请查看我添加到问题中的图片。该按钮仅对绿色背景区域中的触摸做出反应 - 因此按钮似乎没有垂直增长。 @FEK,是的,我认为这就是它的工作方式。我搞砸了好一阵子,发现虽然按钮的titleLabel长到了正确的大小,但按钮本身的大小并没有改变(这就是为什么触摸仍然只在绿色区域有效的原因)。据我所知,你没有错过任何基本的东西。 谢谢 - 这让我发疯了一段时间。我没有办法改变这个吗?问题是我有额外的按钮 - 它们的文本与其他按钮重叠 - 因为约束仅根据绿色区域进行调整...... @FEK,我不知道有什么简单的方法。我认为您需要弄清楚 titleLabel 的高度,然后更改按钮的大小以匹配它。我尝试了我能想到的一切,但无法让它自动更新。 sizeToFit 之类的东西,看起来应该可以工作,但没有 谢谢。我找到了一种计算高度的方法。但是在按钮上设置框架不起作用。请参阅问题的补充。

以上是关于如何在 iOS7 中使用自动布局让按钮垂直增长?的主要内容,如果未能解决你的问题,请参考以下文章

UIViews 到垂直 3D 堆栈

iOS 自定义键盘自动布局

如何在Qt Designer中限制布局的增长(大小)?

如何使用自动布局在屏幕中水平和垂直居中 UILabel?

使用自动布局 VFL 垂直堆叠一组按钮

使用自动布局创建带有文本和图像的 iOS 7 UIButton