iOS Autolayout垂直相等的空间来填充父视图

栏目: IOS · 发布时间: 5年前

内容简介:http://stackoverflow.com/questions/17089427/ios-autolayout-vertically-equal-space-to-fill-parent-view

我有一个视图控制器与12个UITextFields.

它适合3.5“显示非常好.

我需要将其设置为iPhone 5(4英寸显示器),以便所有UITextField通过在其间添加额外的空间覆盖整个UIView.

我试图通过自动布局来做,但是它不能正常工作.

这是我的代码:

- (void) viewWillLayoutSubviews
{
    int h = txt1.bounds.size.height * 12;

    float unusedHorizontalSpace = self.view.bounds.size.height - h ;

    NSNumber* spaceBetweenEachButton=  [NSNumber numberWithFloat: unusedHorizontalSpace / 13 ] ;

    NSMutableArray *constraintsForButtons = [[NSMutableArray alloc] init];

    [constraintsForButtons addObjectsFromArray: [NSLayoutConstraint constraintsWithVisualFormat: @"V:|-50-[txt1(==30)]-(space)-[txt2(==txt1)]-(space)-[txt3(==txt1)]-(space)-[txt4(==txt1)]-(space)-[txt5(==txt1)]-(space)-[txt6(==txt1)]-(space)-[txt7(==txt1)]-(space)-[txt8(==txt1)]-(space)-[txt9(==txt1)]-(space)-[txt10(==txt1)]-(space)-[txt11(==txt1)]-(space)-[txt12]-(space)-|"
                                                                                        options: NSLayoutFormatAlignAllCenterX
                                                                                        metrics: @{@"space":spaceBetweenEachButton}
                                                                                          views: NSDictionaryOfVariableBindings(txt1,txt10,txt11,txt12,txt2,txt3,txt4,txt5,txt6, txt7,txt8,txt9)]];

    [self.view addConstraints:constraintsForButtons];
}

如果我做[txt12(== txt1)],那么它显示与3.5“屏幕相同,并留下下面的空格.

我在哪里犯错?

要使用自动布局执行此操作,您必须创建额外的视图来填充文本字段之间的空格.

回想自动布局约束基本上是线性方程式A = m * B c. A是一个视图的属性(例如,viewA的底边的Y坐标),B是另一个视图的属性(例如,viewB的顶部边缘的Y坐标). m和c是常数.所以,例如,要设置viewA和viewB,以便在viewA的底部和viewB的顶部之间有30个点,我们可以创建一个约束,其中m是1,c是-30.

您遇到的问题是您想要跨13个不同约束使用相同的值,并且您希望自动布局为您计算该c值.汽车布局根本无法做到这一点.不直接自动布局只能计算视图的属性;它不能计算m和c常数.

有一种方法使自动布局将视图放在您想要的位置:将文本字段之间的空格重新列为附加(不可见)视图.这里有一个只有3个文本字段的例子:

iOS Autolayout垂直相等的空间来填充父视图

我们将创建一个约束,将每个间隔件的顶部边缘固定在其上方的文本框的底部边缘.我们还将创建一个约束,将每个间隔件的底部边缘固定到其下方的文本字段的顶部边缘.最后,我们将创建一个约束,以强制每个间隔物具有与顶部间隔物相同的高度.

我们需要一个两个实例变量来设置:文本字段的数组(从上到下的顺序),以及对最顶层间隔视图的引用:

@implementation ViewController {
    NSMutableArray *textFields;
    UIView *topSpacer;
}

我们将在代码中创建文本字段和间隔符,因为在stackoverflow答案中很难显示xib.我们在viewDidLoad中踢东西:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.translatesAutoresizingMaskIntoConstraints = NO;
    [self addTextFields];
    [self addSpacers];
}

由于我们要使用自动布局,所以我们需要关闭translateAutoresizingMaskIntoConstraints来避免系统创建额外的约束.

我们创建每个文本字段,给它一些虚拟文本,并为其水平位置和大小设置约束:

- (void)addTextFields {
    textFields = [NSMutableArray array];
    for (int i = 0; i < 12; ++i) {
        [self addTextField];
    }
}

- (void)addTextField {
    UITextField *field = [[UITextField alloc] init];
    field.backgroundColor = [UIColor colorWithHue:0.8 saturation:0.1 brightness:0.9 alpha:1];
    field.translatesAutoresizingMaskIntoConstraints = NO;
    field.text = [field description];
    [self.view addSubview:field];
    [field setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
    [field setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[field]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(field)]];
    [textFields addObject:field];
}

我们将使用一个环来创建间隔物,但是我们创建了与中间间隔物不同的顶部和底部垫片,因为我们需要将顶部和底部垫片固定在超级视图中:

- (void)addSpacers {
    [self addTopSpacer];
    for (int i = 1, count = textFields.count; i < count; ++i) {
        [self addSpacerFromBottomOfView:textFields[i - 1]
            toTopOfView:textFields[i]];
    }
    [self addBottomSpacer];
}

以下是我们如何创建顶部间隔符并设置其约束.其顶部边缘固定在超级视图中,其底部边缘被固定到第一个(最上面的)文本字段.我们将顶部间隔物存储在实例变量topSpacer中,因此我们可以约束其他间隔物与顶部间隔物具有相同的高度.

- (void)addTopSpacer {
    UIView *spacer = [self newSpacer];
    UITextField *field = textFields[0];
    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:|[spacer][field]" options:0 metrics:nil
        views:NSDictionaryOfVariableBindings(spacer, field)]];
    topSpacer = spacer;
}

以下是我们如何实际创建一个间隔视图.这只是一个隐藏的看法.由于我们不关心它的水平尺寸或位置,我们只将其固定在超级视图的左右边缘.

- (UIView *)newSpacer {
    UIView *spacer = [[UIView alloc] init];
    spacer.hidden = YES; // Views participate in layout even when hidden.
    spacer.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:spacer];
    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"|[spacer]|" options:0 metrics:nil
        views:NSDictionaryOfVariableBindings(spacer)]];
    return spacer;
}

要在两个文本视图之间创建一个“中间”间距,我们将其固定在文本的底部边缘

字段上方和文本字段的上边缘.我们还将其高度限制为等于顶部间隔物的高度.

- (void)addSpacerFromBottomOfView:(UIView *)overView toTopOfView:(UIView *)underView {
    UIView *spacer = [self newSpacer];
    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[overView][spacer(==topSpacer)][underView]" options:0 metrics:nil
        views:NSDictionaryOfVariableBindings(spacer, overView, underView, topSpacer)]];
}

要创建底部间隔符,我们将其固定到最后一个文本字段和超级视图.我们还将其高度限制为等于顶部间隔物的高度.

- (void)addBottomSpacer {
    UIView *spacer = [self newSpacer];
    UITextField *field = textFields.lastObject;
    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[field][spacer(==topSpacer)]|" options:0 metrics:nil
        views:NSDictionaryOfVariableBindings(spacer, field, topSpacer)]];
}

如果你这样做,你会得到如下结果:

iOS Autolayout垂直相等的空间来填充父视图

您可以在 this github repository 找到一个完整的示例项目.

http://stackoverflow.com/questions/17089427/ios-autolayout-vertically-equal-space-to-fill-parent-view


以上所述就是小编给大家介绍的《iOS Autolayout垂直相等的空间来填充父视图》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

虚拟经济学

虚拟经济学

威利•莱顿维塔、爱德华•卡斯特罗诺瓦 / 崔毅 / 中国人民大学出版社 / 2015-6 / 49.00元

电子游戏中也存在 “看不见的手”吗?玩虚拟游戏能够创造真实价值吗?为什么现实世界需要虚拟经济?经济学作为一门成熟的学科,起源于对农业、制造业和商业的探究,曾经作为解决饥饿、就业这些人类所面对的真实问题的方法。然而,在虚拟世界,最为稀缺的资源不再是食物和住所,而是人类的关注度。一些基于农业、制造业和商业存在的经济学理论、概念依然适用于游戏中的虚拟世界,比如最为人们所熟知的“看不见的手”这一概念。同时......一起来看看 《虚拟经济学》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具