将子视图保留为 UIStackView 中的原始尺寸

Posted

技术标签:

【中文标题】将子视图保留为 UIStackView 中的原始尺寸【英文标题】:Keep subviews as original dimensions in UIStackView 【发布时间】:2017-06-24 18:14:39 【问题描述】:

目前我正在尝试在 3 个水平组中制作 3 个具有相等间距的按钮

UIStackView * menuButtons = [[UIStackView alloc] initWithFrame:CGRectMake(0, 0, 60, 16)];
  menuButtons.axis = UILayoutConstraintAxisHorizontal;
  menuButtons.alignment = UIStackViewAlignmentBottom;
  menuButtons.spacing = 6;
  menuButtons.distribution = UIStackViewDistributionEqualSpacing;

UIButton* btnOne = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 16, 16)];
UIButton* btnTwo = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 16, 16)];
UIButton* btnThree = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 16, 16)];

  [menuButtons addArrangedSubview:btnOne];
  [menuButtons addArrangedSubview:btnTwo];
  [menuButtons addArrangedSubview:btnThree];

我注意到,当我以编程方式将按钮视图添加到我的堆栈视图后检查它们的框架时,它们都显示出与最初设置不同的大小,而我希望它们仍然是 16

即:btnOne CGSize(17, 16), btnTwo CGSize(23.5, 23,5), btnThree CGSize(21.3, 21.3)

我不明白为什么会发生这种情况,我已经尝试了所有发行版,但是当我没有在其他任何地方设置这些视图的框架时,我无法弄清楚这一点

【问题讨论】:

据我了解,UIStackView 真的 需要自动布局来layout 其排列的视图。由于您明确设置堆栈视图的框架,并且不允许对其工作进行自动布局/约束,因此您最终会得到意想不到的结果。 【参考方案1】:

这是一个示例 - 基于您的代码 - 使用自动布局约束。

请注意,您不需要为 UIStackView 指定宽度和高度约束,因为它会根据需要扩展以适应排列的子视图。

如果您确实设置了宽度限制,您最终会得到(可能)意想不到的结果,因为您指定了6 的固定宽度间距。

所以,你会想要:

    宽度约束 + UIStackViewDistributionEqualSpacing,或者 没有宽度限制 + 默认分布 + .spacing = 6

希望这会有所帮助...

//
//  StackTestViewController.m
//
//  Created by Don Mag on 6/24/17.
//

#import "StackTestViewController.h"

@interface StackTestViewController ()

@end

@implementation StackTestViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    [self setupMenuButtons];


- (void)setupMenuButtons 

    // instantiate a UIStackView
    UIStackView *menuButtons = [[UIStackView alloc] init];

    // horizontal
    menuButtons.axis = UILayoutConstraintAxisHorizontal;

    // spacing between arranged views
    menuButtons.spacing = 6;

    // instantiate 3 buttons
    UIButton* btnOne = [UIButton new];
    UIButton* btnTwo = [UIButton new];
    UIButton* btnThree = [UIButton new];

    // give 'em background colors so we can see them
    btnOne.backgroundColor = [UIColor redColor];
    btnTwo.backgroundColor = [UIColor greenColor];
    btnThree.backgroundColor = [UIColor blueColor];

    // for each button,
    //  tell it not to use Autoresizing Mask
    //  set width and height constraints each to 16
    for (UIButton *b in @[btnOne, btnTwo, btnThree]) 
        [b setTranslatesAutoresizingMaskIntoConstraints:NO];
        [b.widthAnchor constraintEqualToConstant:16.0].active = YES;
        [b.heightAnchor constraintEqualToConstant:16.0].active = YES;
    

    // add them to the Stack View
    [menuButtons addArrangedSubview:btnOne];
    [menuButtons addArrangedSubview:btnTwo];
    [menuButtons addArrangedSubview:btnThree];

    // add the Stack View to self view
    [self.view addSubview:menuButtons];

    // tell Stack View not to use Autoresizing Mask
    [menuButtons setTranslatesAutoresizingMaskIntoConstraints:NO];

    // set X and Y position for the Stack View (just using 80,80 for this example)
    [menuButtons.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:80.0].active = YES;
    [menuButtons.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:80.0].active = YES;



#end

【讨论】:

以上是关于将子视图保留为 UIStackView 中的原始尺寸的主要内容,如果未能解决你的问题,请参考以下文章

UIStackView 中的多行标签

如何在 UIStackView 中保留隐藏视图的约束

如何在保留选项卡栏的同时将子视图控制器添加到选项卡式视图控制器?

为 UIStackView 中的视图添加大小约束

替换 UIStackView 中的视图

UIStackView 在容器视图中的行为不可预测