使用autolayout

时间:2016-05-19 11:51:41

标签: ios objective-c iphone cocoa-touch autolayout

我有一个UIView子类,我以编程方式创建并添加一些子视图。确切地说,我有6个子视图水平排列,彼此相邻,它们之间没有空格。侧边距(即从我的视图的左边界到第一个子视图的距离以及从我的视图的最后一个子视图到右边界的距离)必须是16pt,并且剩余空间必须在子视图中平均分配。它应该是这样的:

enter image description here

我正在尝试使用autolayout这样做:

NSDictionary *viewsDict = @{@"digit1":digit1, @"digit2":digit2, @"digit3":digit3, @"digit4":digit4, @"digit5":digit5, @"digit6":digit6};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-16-[digit1][digit2(==digit1)][digit3(==digit1)][digit4(==digit1)][digit5(==digit1)][digit6(==digit1)]-16-|" options:0 metrics:nil views:viewsDict]];

当我在具有320pt屏幕视图的iPhone 5上运行时,我希望得到以下结果:

子视图宽度:(320 - 2 * 16)/ 6 = 48

所以帧应该是:

digit1: x =  16, width = 48
digit2: x =  64, width = 48
digit3: x = 112, width = 48
digit4: x = 160, width = 48
digit5: x = 208, width = 48
digit6: x = 256, width = 48

但是,在运行时会发生一件奇怪的事情:我的边距是错误的:

enter image description here

我得到的子视图是:

digit1: x =  21, width = 48
digit2: x =  66, width = 48
digit3: x = 111, width = 48
digit4: x = 156, width = 48
digit5: x = 201, width = 48
digit6: x = 246, width = 48

所以我的左边距是21pt而右边是26pt。此外,子视图重叠3pt。

我已经使用Reveal检查了视图层次结构,我可以确认对于具有正确常数16的边距的约束。但是帧由于某种原因是不同的。似乎没有任何其他冲突的约束,在运行应用程序时也没有出现自动布局错误。

谁能看到我在这里缺少的东西?

修改

使用间隔视图测试Aloks建议而不是间距约束我试过这个:

UIView *spacer1 = [[UIView alloc] init];
UIView *spacer2 = [[UIView alloc] init];
spacer1.translatesAutoresizingMaskIntoConstraints = NO;
spacer2.translatesAutoresizingMaskIntoConstraints = NO;
spacer1.backgroundColor = [UIColor redColor];
spacer2.backgroundColor = [UIColor redColor];
[self addSubview:spacer1];
[self addSubview:spacer2];
NSDictionary *viewsDict = @{@"spacer1":spacer1, @"digit1":digit1, @"digit2":digit2, @"digit3":digit3, @"digit4":digit4, @"digit5":digit5, @"digit6":digit6, @"spacer2":spacer2};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spacer1(16)][digit1][digit2(==digit1)][digit3(==digit1)][digit4(==digit1)][digit5(==digit1)][digit6(==digit1)][spacer2(16)]|" options:0 metrics:nil views:viewsDict]];

这给了我以下结果:

enter image description here

如您所见,间隔视图位置正确,但数字子视图保持原样。

3 个答案:

答案 0 :(得分:1)

你的约束应该是:

equal width与彼此的每个观点

每个观点

fixed height

每个视图都

leading,trailing and top or bottom (which is appropriate)

它会正常工作

查看此约束的输出

enter image description here

你只需要在代码中转换它!!!!

如果您以编程方式添加视图,那么如何设置视图的框架也很重要。根据屏幕尺寸,您的框架应该是动态的。

希望这会有所帮助:)

答案 1 :(得分:1)

您将{16}用作require(data.table) require(sqldf) x1 <- c(1,1,2,1,NA) x2 <- c(1,3,3,NA,NA) x <- data.table(rbind(x1,x2)) colnames(x) <- c("ID", "x1", "x2", "x3", "x4") sqldf("select ID, max(x1) as x1, max(x2) as x2, max(x3) as x3, max(x4) as x4 from x group by ID") ID x1 x2 x3 x4 1 1 3 3 1 NA leading的方式,而不是trailing

以这种方式写下spacer1 (UIView *spacer1) and spacer2 (UIView *spacer2)

VFL

它应该有用。

OUTPUT

答案 2 :(得分:0)

我终于解决了我的问题,问题实际上是在其他地方。我不是这个项目的唯一开发人员,我没有意识到(这是一个大班级)其他人一直在layoutSubviews方法中手动设置子视图的位置,如下所示:

- (void)layoutSubviews {
    [super layoutSubviews];

    // set center for each digit view
}

当然,由于位置是在[super layoutSubviews]之后设置的,因此它改变了我的自动布局约束设置的位置。

我要感谢所有在这里做出贡献的人。您的解决方案帮助我确认我的原始解决方案实际上是正确的,并迫使我在其他地方寻找问题。