在没有边距的视图中均匀分布

Posted

技术标签:

【中文标题】在没有边距的视图中均匀分布【英文标题】:Space evenly across a view without margins 【发布时间】:2015-03-11 10:01:10 【问题描述】:

我使用以下函数在一个视图中分隔动态数量的视图(使用自动布局):

-(NSArray*)spaceViews:(NSArray *)views onAxis:(UILayoutConstraintAxis)axis

    NSAssert([views count] > 1,@"Can only distribute 2 or more views");

    NSLayoutAttribute attributeForView;
    NSLayoutAttribute attributeToPin;

    switch (axis) 
        case UILayoutConstraintAxisHorizontal:
            attributeForView = NSLayoutAttributeCenterX;
            attributeToPin = NSLayoutAttributeRight;
            break;
        case UILayoutConstraintAxisVertical:
            attributeForView = NSLayoutAttributeCenterY;
            attributeToPin = NSLayoutAttributeBottom;
            break;
        default:
            return @[];
    

    CGFloat fractionPerView = 1.0 / (CGFloat)([views count] + 1);

    NSMutableArray *constraints = [NSMutableArray array];
    [views enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop)
    
        CGFloat multiplier = fractionPerView * (idx + 1.0);
        [constraints addObject:[NSLayoutConstraint constraintWithItem:view 
                                                            attribute:attributeForView 
                                                            relatedBy:NSLayoutRelationEqual 
                                                               toItem:self 
                                                            attribute:attributeToPin 
                                                           multiplier:multiplier 
                                                             constant:0.0]];
    ];

    [self addConstraints:constraints];
    return [constraints copy];

(函数来自UIView-Autolayout)

问题是它有边距。如何更改此方法以均匀分布没有边距的视图?

更新

似乎该方法最终无法正常工作,外部项目的边距比其他项目高得多。

例如,我将左臂的代码更改为:

self.leftArm = [UIView autoLayoutView];
self.leftArm.backgroundColor = [UIColor grayColor];

[self.view addSubview:self.leftArm];

[self.leftArm pinAttribute:NSLayoutAttributeRight toAttribute:NSLayoutAttributeLeft ofItem:self.body withConstant:-10.0];
[self.leftArm pinAttribute:NSLayoutAttributeTop toSameAttributeOfItem:self.body withConstant:10.0];
[self.leftArm constrainToSize:CGSizeMake(20.0, 200.0)];

现在机器人看起来像这样:

请注意,在左臂,视图分布不均,顶部和底部的边距要高得多。我可以用更少的项目水平再现相同的行为。

通过将外部视图与超级视图的侧面对齐并在其间的空间内对齐其余部分,我已成功删除了边距。但是现在,由于这个问题,我总是在外部视图和旁边的视图之间留出更大的空间。

有谁知道如何解决这个问题?

更新 2

我创建了一个 fork 并向其中添加了我的功能,我还扩展了机器人示例,以便您了解我的意思。

请take a look。

【问题讨论】:

我知道那个代码 :D 我不确定你所说的边距注释是什么意思 - 你的意思是你想让边缘视图与超级视图的边缘对齐吗? @jrturton 是的,其余视图均匀分布 尊敬的同事 James Frost 为您服务 【参考方案1】:

看起来这段代码来自UIView-Autolayout。最新版本的库有一个新方法可以让你停止将间距添加到边缘:

-(NSArray*)spaceViews:(NSArray*)views
               onAxis:(UILayoutConstraintAxis)axis
          withSpacing:(CGFloat)spacing
     alignmentOptions:(NSLayoutFormatOptions)options
    flexibleFirstItem:(BOOL)flexibleFirstItem
  applySpacingToEdges:(BOOL)spaceEdges;

只需调用此方法并将NO 传递给最后一个参数。

【讨论】:

不幸的是,该方法有一个参数“spacing”,其中定义了视图之间的距离。 (我已经试过了) 你可以传递 0 作为间距吗?如果您不希望视图之间有间距,那么您发布的原始方法没有按照您的意愿执行是什么? 在这种情况下,我不确定您想要什么。 spaceViews:onAxis 方法沿轴均匀分布视图的中心,让它们占据自己的固有大小。带间距的方法计算宽度并强制它们占据相等的宽度。如果视图大小不同,如何使间距“均匀”? 我添加的视图是 UIImageViews,它们通过这个功能得到扩展(我发布的那个有边距)。但是现在我想起来了,我可以将它们集中在另一个可以扩展的视图中......问题解决了! 我的第一个想法是将第一个视图左对齐,最后一个右对齐,并将其余部分均匀地分布在视图上——两个视图占用的空间。但这更难。而且我不确定是否可以在不使用框架的情况下获得第一个和最后一个视图的大小【参考方案2】:

我扩展了jrturton's UIView-Autolayout(基于this answer)并创建了一个pull request。

现在可以通过调用新函数来均匀分布视图而没有边距:

-(NSArray*)spaceViews:(NSArray *)views 
               onAxis:(UILayoutConstraintAxis)axis
           withMargin:(BOOL)margin

并将边距参数设置为NO

你已经可以找到那个版本的 UIView-Autolayout here。

全新的机器人,具有均匀分布的视图作为牙齿:

【讨论】:

以上是关于在没有边距的视图中均匀分布的主要内容,如果未能解决你的问题,请参考以下文章

尝试更改 iOS 中私有视图的布局边距的客户端错误

限制为边距的堆栈视图不会留下任何余量

iOS Autolayout:如何显示/隐藏包含边距的视图?

如何删除不希望保留超级视图继承边距的 tableView 单元格的顶部和左侧边距?

对边距的影响?

以编程方式创建绑定到视图控制器边距的约束