【问题标题】:AutoLayout - equal heights based on taller viewAutoLayout - 基于更高视图的相等高度
【发布时间】:2022-01-10 15:50:14
【问题描述】:

这在概念上类似于 Autolayout height equal to MAX(multiple view heights),除了问题是调整容器视图的大小,但我希望将两个按钮的大小调整为最大高度按钮的高度。


我在视图的页脚部分有两个并排的按钮。我希望按钮具有相同的宽度,因此我应用了一个约束以使它们具有相同的宽度并且效果很好。我还希望它们具有相同的高度,以防其中一个按钮最终占用超过一行的标题。我尝试将两个按钮的高度设置为相同,但是当我这样做时,在确定两个按钮的高度时总是使用较短的按钮。例如,如果第一个按钮只有一行文本,而第二个按钮是三行文本,则两个按钮的大小都将仅适用于一行文本。如果交换文本以使第一个按钮应该更高,也会发生同样的事情。

我也为两个按钮设置了内容拥抱和抗压缩优先级,但这似乎仍然没有帮助,或者我设置错误。

[self->_firstButton setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
[self->_firstButton setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        
[self->_firstButton setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
[self->_firstButton setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical];

并且为第二个按钮设置了相同的优先级。

以下是使两个按钮大小相同的约束条件,这些约束条件确实有效,因为按钮宽度相同,高度相同,但问题再次是高度是较短按钮的高度(按钮具有较短的标题文本)。

[self.firstButton.heightAnchor constraintEqualToAnchor:self.secondButton.heightAnchor],
[self.firstButton.widthAnchor constraintEqualToAnchor:self.secondButton.widthAnchor]

有人知道我做错了什么吗?或者有谁知道如何解决这个问题,以便两个按钮都将是较高按钮(具有较长标题的按钮)的高度,而不是具有较短标题的按钮的高度?

【问题讨论】:

  • "第二个按钮是三行文本" -- 你用什么代码来允许按钮中有三行文本?或者,您使用的是新的 iOS 15 样式按钮吗?
  • @DonMag 实际上是一个自定义的 UIControl 子类,实现了按钮的功能。在自定义按钮类中,标题只是一个标签,默认情况下 numberOfLines 设置为零,文本将换行为多行,如果按钮的宽度受到限制,按钮将在高度上扩展(在这种情况下,因为每个按钮都是大约是包含父视图宽度的一半)。它在概念上类似于新的 iOS 15 按钮,只是我需要能够支持 iOS 13+。
  • @DonMag (continued, 2 of 3) 然而,对于这个问题,我们甚至可以更改它,以便我们可以谈论等大小的标签,而不是等大小的按钮,因为这实际上是相同的问题。基本上,我只是不知道如何使具有不同高度的两个标签(或任何视图)成为最高视图的高度。因此,如果一个标签(或按钮)有一行,另一个有三行,我希望较短的视图的大小与较高的视图相同,这样它们的高度相同且没有内容丢失了。
  • 听起来您的自定义控件与自动布局有冲突。此快速示例代码:pastebin.com/Y3WEhGrL 在堆栈视图中使用两个标签,结果为:i.stack.imgur.com/LazGG.png
  • 抱歉 - 以为您使用的是堆栈视图(为什么不呢?)。如果您真的不想这样做,那么如果没有运行时代码计算两个控件的高度,然后设置约束以匹配最高的那个,您就无法做到这一点。另一种选择是将它们嵌入到视图中,并限制顶部和底部......较高的视图将使视图更高,这将拉伸较短的高度。

标签: ios cocoa-touch uibutton autolayout


【解决方案1】:

我的 cmets 不太正确...

如果您已在自定义视图/控件中正确设置了约束,或者如果您正确设置了其固有大小,则只需很少的时间即可获得所需的结果约束...即使视图不包含在堆栈视图或其他“容器”视图中。

例如这段代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UILabel *v1 = [UILabel new];
    v1.backgroundColor = [UIColor cyanColor];
    v1.textAlignment = NSTextAlignmentCenter;
    v1.numberOfLines = 0;
    v1.text = @"One Line";
    
    UILabel *v2 = [UILabel new];
    v2.backgroundColor = [UIColor greenColor];
    v2.textAlignment = NSTextAlignmentCenter;
    v2.numberOfLines = 0;
    v2.text = @"Lots of text to force the label to wrap onto multiple lines.";

    for (UIView *v in @[v1, v2]) {
        v.translatesAutoresizingMaskIntoConstraints = NO;
        [self.view addSubview:v];
    }
    
    UILayoutGuide *g = [self.view safeAreaLayoutGuide];

    [NSLayoutConstraint activateConstraints:@[
        
        [v1.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
        [v2.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
        
        [v1.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-20.0],
        [v2.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-20.0],

        [v1.widthAnchor constraintEqualToAnchor:v2.widthAnchor],
        [v2.leadingAnchor constraintEqualToAnchor:v1.trailingAnchor constant:20.0],
        
        [v1.heightAnchor constraintEqualToAnchor:v2.heightAnchor],
        
    ]];
    
    // not striclty needed, but to make sure they don't compress
    [v1 setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
    [v2 setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
}

产生这个结果:

并且,通过仅更改两个标签中的文本

【讨论】:

  • 再次感谢您帮助解决此问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 2013-11-03
  • 2013-01-16
  • 1970-01-01
  • 2017-07-19
相关资源
最近更新 更多