not*_*bob 273 rotation spacing ios autolayout ios6
自动布局让我的生活变得困难.从理论上讲,当我切换时它会非常有用,但我似乎总是在打架.
我做了一个演示项目试图找到帮助.有没有人知道如何在调整视图大小时使视图之间的间距均匀增加或减少?
这是三个标签(手动间隔垂直):

我想要的是让他们在旋转时均匀地调整间距(而不是视图大小).默认情况下,顶视图和底视图朝中心方向挤压:

smi*_*Bot 312
看,没有间隔!
根据我原来答案评论部分的建议,特别是@Rivera的有用建议,我简化了原来的答案.
我正在使用GIF来说明这是多么简单.我希望你能找到有用的GIF.为了防止您遇到GIF问题,我在下面用简单的屏幕截图包含了旧答案.
说明:
1)添加按钮或标签.我正在使用3个按钮.
2)从每个按钮向superview添加一个中心x约束:

3)从每个按钮添加约束到底部布局约束:

4)调整上面#3中添加的约束如下:
a)选择约束, b)删除常量(设置为0), c)按如下方式更改乘数:取按钮数+ 1,从顶部开始,将乘数设置为buttonCountPlus1:1,然后按buttonCountPlus1 :2,最后是buttonCountPlus1:3.(如果你感兴趣,我会在下面的旧答案中解释我从哪里得到这个公式).

5)这是一个运行的演示!

注意:如果按钮的高度较大,则需要在常量值中对此进行补偿,因为约束来自按钮的底部.
老答案
尽管Apple的文档和Erica Sadun的优秀书籍(Auto Layout Demystified)所说,但是可以在没有间隔符的情况下均匀地观看视图.这在IB和代码中非常简单,可以平均分配任意数量的元素.您只需要一个称为"部分公式"的数学公式.它比解释更简单.我将通过在IB中展示它来尽力而为,但它在代码中也很容易.
在这个例子中,你会的
1)首先将每个标签设置为具有中心约束.这很简单.只需控制从每个标签拖动到底部.
2)按住shift,因为您可能还要添加我们将要使用的其他约束,即"底部空间到底部布局指南".
3)选择"底部空间到底部布局指南","水平居中容器".对所有3个标签执行此操作.

基本上,如果我们采用我们希望确定其坐标的标签并将其除以标签总数加1,那么我们可以添加一个数字以获得动态位置.我正在简化公式,但你可以用它同时设置水平间距或垂直和水平.它超级强大!
这是我们的乘数.
Label1 = 1/4 = .25,
Label2 = 2/4 = .5,
Label3 = 3/4 = .75
(编辑:@Rivera评论说你可以直接在乘数字段中使用比率,并使用xCode进行数学运算!)
4)所以,让我们选择Label1并选择底部约束.像这样:

5)在Attributes Inspector中选择"Second Item".
6)从下拉列表中选择"反向第一和第二项".
7)将常量和wC hAny值清零.(如果需要,可以在这里添加偏移量).
8)这是关键部分:在乘数字段中添加第一个乘数0.25.
9)当你在它时,将顶部的"第一项"设置为"中心",因为我们希望将它居中到标签的y中心.这是所有应该看起来的样子.

10)对每个标签重复此过程并插入相关乘数:Label2为0.5,Label3为0.75.这是所有紧凑型设备的最终产品!超级简单.我一直在寻找很多涉及大量代码和间隔器的解决方案.这是我在这个问题上看到的最好的解决方案.
更新:@kraftydevil补充说,底部布局指南仅出现在故事板中,而不是出现在xib中.在xib中使用'Bottom Space to Container'.接得好!

小智 207
所以我的方法允许你在界面构建器中执行此操作.您所做的是创建"间隔视图",您已将其设置为与高度相等.然后为标签添加顶部和底部约束(请参见屏幕截图).

更具体地说,我对'Spacer View 1'有一个顶级约束,使用高于1000的高度约束和高度等于所有其他'spacer视图'的超视图.'Spacer View 4'对superview有一个底部空间约束.每个标签对其最近的"间隔视图"具有相应的顶部和底部约束.
注意:确保您的标签上没有额外的顶部/底部空间限制到superview; 只是那些'空间视图'.这将是令人满意的,因为顶部和底部约束分别在"空间视图1"和"间隔视图4"上.
Duh 1:我复制了我的视图,只是将它放在横向模式中,这样你就可以看到它有效了.
Duh 2:'spacer views'可能是透明的.
Duh 3:这种方法可以横向应用.
Met*_*ete 93
非常快速的Interface Builder解决方案:
对于在超视图中均匀分布的任意数量的视图,只需为每个水平布局提供"Align Center X to superview"约束,或者为垂直布局选择"Align Center Y superview",并将Multiplier设置为N:p(注意:一些可以有更好的运气p:N-见下文)
哪里
N = total number of views,和
p = position of the view including spaces
第一个位置是1,然后是一个空格,使下一个位置3,所以p成为一个系列[1,3,5,7,9,...].适用于任意数量的视图.
所以,如果你有3个空间视图,它看起来像这样:

编辑注意:选择N:p或p:N取决于对齐约束的关系顺序.如果"First Item"是Superview.Center,您可以使用p:N,而如果Superview.Center是"Second Item",您可以使用N:p.如果有疑问,只需尝试两个...... :-)
Glo*_*del 66
从iOS 9开始,Apple已经(期待已久)让这一切变得非常简单UIStackView.只需在Interface Builder中选择要包含的视图,然后选择编辑器 - >嵌入 - >堆栈视图.为堆栈视图设置适当的宽度/高度/边距约束,并确保将Distribution属性设置为"Equal spacing":

当然,如果您需要支持iOS 8或更低版本,则必须选择其他选项之一.
jrt*_*ton 50
我一直在乘坐过山车,喜欢自动布局和讨厌它.爱它的关键似乎是接受以下内容:
也就是说,您尝试的并不简单,并且很难在界面构建器中实现.在代码中执行起来非常简单.此代码在viewDidLoad,创建和定位三个标签,如何询问它们:
// Create three labels, turning off the default constraints applied to views created in code
UILabel *label1 = [UILabel new];
label1.translatesAutoresizingMaskIntoConstraints = NO;
label1.text = @"Label 1";
UILabel *label2 = [UILabel new];
label2.translatesAutoresizingMaskIntoConstraints = NO;
label2.text = @"Label 2";
UILabel *label3 = [UILabel new];
label3.translatesAutoresizingMaskIntoConstraints = NO;
label3.text = @"Label 3";
// Add them all to the view
[self.view addSubview:label1];
[self.view addSubview:label2];
[self.view addSubview:label3];
// Center them all horizontally
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
// Center the middle one vertically
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
// Position the top one half way up
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeCenterY multiplier:0.5 constant:0]];
// Position the bottom one half way down
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeCenterY multiplier:1.5 constant:0]];
Run Code Online (Sandbox Code Playgroud)
正如我所说,这个代码在几个类别方法中大大简化了UIView,但为了清楚起见,我已经完成了很长的路要走.
类别是这里对于那些有兴趣,并且其具有用于沿特定轴均匀间隔的视图的阵列的方法.
Ben*_*man 20
大多数这些解决方案都依赖于奇数个项目,因此您可以将中间项目放在中间位置.如果您仍然希望均匀分配偶数项目,该怎么办?这是一个更通用的解决方案.此类别将沿垂直轴或水平轴均匀分布任意数量的项目.
在superview中垂直分布4个标签的示例用法:
[self.view addConstraints:
[NSLayoutConstraint constraintsForEvenDistributionOfItems:@[label1, label2, label3, label4]
relativeToCenterOfItem:self.view
vertically:YES]];
Run Code Online (Sandbox Code Playgroud)
NSLayoutConstraint + EvenDistribution.h
@interface NSLayoutConstraint (EvenDistribution)
/**
* Returns constraints that will cause a set of views to be evenly distributed horizontally
* or vertically relative to the center of another item. This is used to maintain an even
* distribution of subviews even when the superview is resized.
*/
+ (NSArray *) constraintsForEvenDistributionOfItems:(NSArray *)views
relativeToCenterOfItem:(id)toView
vertically:(BOOL)vertically;
@end
Run Code Online (Sandbox Code Playgroud)
NSLayoutConstraint + EvenDistribution.m
@implementation NSLayoutConstraint (EvenDistribution)
+(NSArray *)constraintsForEvenDistributionOfItems:(NSArray *)views
relativeToCenterOfItem:(id)toView vertically:(BOOL)vertically
{
NSMutableArray *constraints = [NSMutableArray new];
NSLayoutAttribute attr = vertically ? NSLayoutAttributeCenterY : NSLayoutAttributeCenterX;
for (NSUInteger i = 0; i < [views count]; i++) {
id view = views[i];
CGFloat multiplier = (2*i + 2) / (CGFloat)([views count] + 1);
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
attribute:attr
relatedBy:NSLayoutRelationEqual
toItem:toView
attribute:attr
multiplier:multiplier
constant:0];
[constraints addObject:constraint];
}
return constraints;
}
@end
Run Code Online (Sandbox Code Playgroud)
smi*_*org 17
查看开源库PureLayout.它提供了一些用于分发视图的API方法,包括每个视图之间的间距固定的视图(视图大小根据需要变化),以及每个视图的大小固定的位置(视图之间的间距根据需要而变化).请注意,所有这些都是在不使用任何"间隔视图"的情况下完成的.
// NSArray+PureLayout.h
// ...
/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. */
- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis
alignedTo:(ALAttribute)alignment
withFixedSpacing:(CGFloat)spacing;
/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. */
- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis
alignedTo:(ALAttribute)alignment
withFixedSize:(CGFloat)size;
// ...
Run Code Online (Sandbox Code Playgroud)
由于它是全部开源的,如果您有兴趣了解如何在没有间隔视图的情况下实现这一点,只需看一下实现.(这取决于利用constant 和 multiplier约束.)
Ole*_*nov 17
正确和最简单的方法是使用堆栈视图.
我遇到了类似的问题并发现了这篇文章.但是,当前提供的答案都没有以您希望的方式解决问题.它们不会使间距相等,而是平均分配标签的中心.重要的是要明白这是不一样的.我构建了一个小图来说明这一点.

共有3个视图,全部高20pt.使用任何建议的方法均匀分布视图的中心并为您提供图示的布局.请注意,视图的y中心间隔相等.但是,superview和顶视图之间的间距是15pt,而子视图之间的间距只有5pt.为了使视图间隔均匀,这些视图应均为10pt,即所有蓝色箭头应为10pt.
尽管如此,我还没有想出一个好的通用解决方案.目前我最好的想法是在子视图之间插入"间距视图",并将间距视图的高度设置为相等.
我完全可以在IB中解决这个问题:
因此,如果您有三个标签,请将每个约束的乘数设置为0.1666667,0.5,0.833333.
我发现了一种完美而简单的方法.自动布局不允许您平均调整空间大小,但它允许您平均调整视图大小.只需在字段之间放置一些不可见的视图,并告诉自动布局以保持它们的大小相同.它完美无缺!


但有一点需要注意; 当我缩小界面设计器的大小时,有时它会混淆并留下标签,如果大小改变了奇数,就会产生冲突.否则它完美无缺.
编辑:我发现冲突成了问题.因此,我采用了一个间距约束,将其删除并用两个约束替换它,大于或等于和小于或等于.两者的大小相同,优先级低于其他约束.结果是没有进一步的冲突.
| 归档时间: |
|
| 查看次数: |
125286 次 |
| 最近记录: |