Ios 在水平堆栈视图中禁用按钮宽度和高度

Ios 在水平堆栈视图中禁用按钮宽度和高度,ios,xcode,Ios,Xcode,我现在正在学习iOS开发,XCode不允许我编辑堆栈视图中按钮的宽度和高度: 在故事板中,我创建了一个大小为30 x 30的新按钮,带有一个自定义图像,然后再复制该按钮的5个副本。然后,我在堆栈视图中选择所有对象后嵌入它们。现在发生了一场灾难,按钮被调整到了上帝知道的大小,它们看起来很大。当我试图去尺寸检查器调整按钮的大小时,我看到“宽度”和“高度”字段被禁用 我尝试了一些关于stackoverflow的建议,选择了stack视图,并将stack视图的分布更改为“平均填充”,但按钮大小仍在更改。

我现在正在学习iOS开发,XCode不允许我编辑堆栈视图中按钮的宽度和高度:

在故事板中,我创建了一个大小为30 x 30的新按钮,带有一个自定义图像,然后再复制该按钮的5个副本。然后,我在堆栈视图中选择所有对象后嵌入它们。现在发生了一场灾难,按钮被调整到了上帝知道的大小,它们看起来很大。当我试图去尺寸检查器调整按钮的大小时,我看到“宽度”和“高度”字段被禁用

我尝试了一些关于stackoverflow的建议,选择了stack视图,并将stack视图的分布更改为“平均填充”,但按钮大小仍在更改。我不想发生这种事。我希望在水平堆栈视图中有一个固定大小的按钮,并且将它们放在堆栈视图中不应该像这样改变按钮的大小或形状。谁能告诉我如何解决这个问题

请帮忙


有时接口生成器不容易处理,因为它在
设计时是一个运行的布局系统
/
ibu DESIGNABLE
。您进行了更改,IB被触发“思考”,再次更改参数、布局,您看到它不适合,然后再次更改。
在删除将通过将子视图的
intrinsicContentSize
纳入其计算来安排的内容之前,可以更容易地将
UIStackView
的约束固定到外部布局。更糟糕的是,如果stackview还没有完整的约束,而您按排列方式放入了某些内容,则它会将默认大小作为已删除视图的intrinsicContentSize,并按其应做的更改stackview间距。这并不奇怪,但也可能令人沮丧,因为这里的便利性干扰了您的工作流程

文档告诉您不应更改
intrinsicContentSize
,因为它不应设置动画,甚至会干扰动画和布局,甚至会破坏约束。嗯,您不能设置
内部内容大小
,它是只读的。因为这是有充分理由的,他们可以写下,虽然UIView是实例,但它们可以有支持性的变量,这些变量必须在布局之前设置,这允许您进行预先计算

虽然在代码中这也可能很棘手,但您可以将UIView子类化,以使排列的子视图实例更支持您的需要

UIView的
invalidateIntrinsicContentSize
触发版面将更改的intrinsicContentSize带入下一个版面周期。您仍然无法设置intrinsicContentSize,但如果您想要设计如下所示的类,则不需要设置intrinsicContentSize

// IntrinsicView.h
@import UIKit
IB_DESIGNABLE
@interface IntrinsicView : UIView
-(instancetype)initWithFrame:(CGRect)rect;
@property IBInspectable CGFloat intrinsicHeight;
@property IBInspectable CGFloat intrinsicWidth;
@end
现在,这使您可以控制
UIStackView
将布局时的行为。
让我们看一下视图的实例

#import "IntrinsicView.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIStackView *column = [[UIStackView alloc] initWithFrame:self.view.frame];
    column.spacing = 2;
    column.alignment = UIStackViewAlignmentFill;
    column.axis = UILayoutConstraintAxisVertical; //Up-Down
    column.distribution = UIStackViewDistributionFillEqually;
    
    CGFloat quadratur = 30.0;
    for (int row=0; row<5; row++) {
        IntrinsicView *supportiveView = [[IntrinsicView alloc] initWithFrame:CGRectMake(0, 0, quadratur, quadratur)];
        // supportiveView stuff here..
        [column addArrangedSubview:supportiveView];
    }
    
    [self.view addSubview:column];
}
#导入“IntrinsicView.h”
-(无效)viewDidLoad{
[超级视图下载];
UIStackView*列=[[UIStackView alloc]initWithFrame:self.view.frame];
柱间距=2;
column.alignment=UIStackViewAlignmentFill;
column.axis=UILayoutConstraintaxVertical;//向上向下
column.distribution=UIStackViewDistributionAllegally;
CGFloat quadraur=30.0;

for(int row=0;row有时接口生成器不容易处理,因为它在
设计时是一个运行的布局系统
/
IB_DESIGNABLE
。您进行更改,IB被触发“思考”,再次更改参数、布局,您看到它不适合,然后再次更改。
在将子视图的
intrinsicContentSize
放入计算中来安排内容之前,将
UIStackView
的约束固定到外部布局可能会更容易。更糟糕的是,如果stackview没有完整的约束,而您将某个内容作为安排放入,则它将采用default size为已删除视图的intrinsicContentSize,并根据需要更改堆栈视图间距。这并不奇怪,但可能会令人沮丧,因为这里的便利性干扰了您的工作流程

文档告诉您不应该更改
intrinsicContentSize
,因为它不是用来设置动画的,它甚至会干扰动画和布局,甚至会破坏约束。嗯,您不能设置
intrinsicContentSize
,它是只读的。因为有充分的理由,他们可以在UIView是实例,它们可以有支持性变量,这些变量必须在布局之前设置,以便进行预先计算

虽然在代码中这也可能很棘手,但您可以将UIView子类化,以使排列的子视图实例更支持您的需要

UIView的
invalidateIntrinsicContentSize
会触发布局,将更改的intrinsicContentSize带入下一个布局周期。您仍然无法设置intrinsicContentSize,但如果要设计如下所示的类,则不需要设置intrinsicContentSize

// IntrinsicView.h
@import UIKit
IB_DESIGNABLE
@interface IntrinsicView : UIView
-(instancetype)initWithFrame:(CGRect)rect;
@property IBInspectable CGFloat intrinsicHeight;
@property IBInspectable CGFloat intrinsicWidth;
@end
现在,这使您可以控制
UIStackView
将布局时的行为。
让我们看一下视图的实例

#import "IntrinsicView.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIStackView *column = [[UIStackView alloc] initWithFrame:self.view.frame];
    column.spacing = 2;
    column.alignment = UIStackViewAlignmentFill;
    column.axis = UILayoutConstraintAxisVertical; //Up-Down
    column.distribution = UIStackViewDistributionFillEqually;
    
    CGFloat quadratur = 30.0;
    for (int row=0; row<5; row++) {
        IntrinsicView *supportiveView = [[IntrinsicView alloc] initWithFrame:CGRectMake(0, 0, quadratur, quadratur)];
        // supportiveView stuff here..
        [column addArrangedSubview:supportiveView];
    }
    
    [self.view addSubview:column];
}
#导入“IntrinsicView.h”
-(无效)viewDidLoad{
[超级视图下载];
UIStackView*列=[[UIStackView alloc]initWithFrame:self.view.frame];
柱间距=2;
column.alignment=UIStackViewAlignmentFill;
column.axis=UILayoutConstraintaxVertical;//向上向下
column.distribution=UIStackViewDistributionAllegally;
CGFloat quadraur=30.0;

对于(int row=0;row将带有约束的按钮添加到UIView中,然后再复制该视图的5个副本。在按钮和视图之间更改约束。@SonPham我想你不明白这个问题,我说过我将所有6个按钮嵌入了一个水平堆栈视图中。这应该只是以相等的距离排列按钮,当然不是c改变大小或形状