用于程序生成的视图的自动布局实现

9

我有一个应用程序,其视图是通过编程生成的。例如:

-(void)loadView
{
    [super loadView];

// SET TOP LEFT BTN FOR NEXT VIEW
UIBarButtonItem *topLeftBtn = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = topLeftBtn;
[topLeftBtn release];

// programmatically set up the view for cart tableView
CGRect iouTableViewFrame = CGRectMake(0, 0, 320, 348);
iouTableView = [[UITableView alloc]initWithFrame:iouTableViewFrame style:UITableViewStylePlain];
[[self iouTableView] setDelegate:self];
[[self iouTableView] setDataSource:self];
[[self view] addSubview:iouTableView];

// set up the summary label
CGRect summaryTableFrame = CGRectMake(0, 348, 320, 18);
UILabel *summaryTableLabel = [[UILabel alloc] initWithFrame:summaryTableFrame];
[summaryTableLabel setFont:[UIFont fontWithName:@"Helvetica" size:14]];
[summaryTableLabel setText:@"   Summary"];
UIColor *labelColor = UIColorFromRGB(MiddleBlueColor);
[summaryTableLabel setBackgroundColor:labelColor];
[summaryTableLabel setTextColor:[UIColor whiteColor]];
[[self view] addSubview:summaryTableLabel];

// set up the summary table
CGRect summaryTableViewFrame = CGRectMake(0, 366, 320, 44);
summaryTableView = [[UITableView alloc]initWithFrame:summaryTableViewFrame style:UITableViewStylePlain];
[summaryTableView setScrollEnabled:NO];
[[self summaryTableView] setDelegate:self];
[[self summaryTableView] setDataSource:self];
[[self view] addSubview:summaryTableView];
}

是的。我会将来更新到 NIBs 并使用接口生成器和故事板,但我已经有一年没有做 iOS 编程了。
由于新的 iPhone 5 具有不同的屏幕大小,应用程序看起来并不好看,因此我需要实现某种自动布局。现在是否有一种编程方式来实现它,而不是使用 IB?
非常感谢!
2个回答

31

有的,可以通过NSLayoutConstraint中的两种方法实现

-(NSArray*)constraintsWithVisualFormat:options:metrics:views:
-(NSLayoutConstraint*)constraintWithItem:attribute:relatedBy:toItem:attribute:
    multiplier:constant:

可视化格式语言被打包成了一个NSString。所以我会以你的iouTableView为例。
[self.view addConstraints:[NSLayoutConstraint 
    constraintsWithVisualFormat:@"|[iouTableView]|" 
    options:0 
    metrics:nil 
    views:NSDictionaryOfVariableBindings(iouTableView)]];

管道符号 "|" 代表父视图的边缘。 方括号 "[]" 代表一个视图。 所以我们所做的就是将 iouTableView 的左右边缘连接到其父视图的左右边缘。

另一个可视化格式的示例: 让我们垂直地连接您的表视图、摘要标签和摘要表。

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:
    @"V:|[iouTableView(348)][summaryTableLabel(18)][summaryTableView(44)]"
    options:NSLayoutFormatAlignAllLeft
    metrics:nil
    views:NSDictionaryOfVariableBindings(iouTableView, summaryTableLabel, summaryTableView)]];

现在,这将垂直地连接三个视图,每个视图都在它们的边缘上对齐。NSLayoutFormatAlignAllLeft告诉所有的视图左对齐,并且它们将根据其他约束来进行对齐,例如前一个约束。()用于指定视图的大小。
还有一些不等式和优先级,以及“-”间隔符号,但是请查看苹果文档
编辑:更正示例,使用constraintsWithVisualFormat,如方法签名所示。

你的第二个示例是否也需要将其他两个视图添加到绑定名称为对象的NSDictionary中?即NSDictionaryOfVariableBindings(iouTableView,summaryTableLabel,summaryTableView)而不仅仅是iouTableView - nmr
是的,它确实有问题,我现在来修复它! - David Wong
@David Wong,使用UITableView和UIButton也可以实现这个吗?但是当我使用这个方法时,会触发一个未捕获的NSException,导致[self.view addConstraints...]出错。 - P Griep
你不应该将不是单元格/页脚/页眉/部分等的内容添加到UITableView中。如果你想在表视图上放置按钮,最好使用一些视图控制器容器。如果这不是你要找的答案,请考虑提出一个新问题。 - David Wong

1
除了苹果提供的方法外,您还可以使用Parus库来从代码中操作AutoLayout。例如,您将能够指定:
PVVFL(@"[view1]-20-[view2]").fromRightToLeft.withViews(views).asArray

代替

[NSLayoutConstraint constraintsWithVisualFormat:@"[view1]-20-[view2]"
                                        options:NSLayoutFormatDirectionRightToLeft
                                        metrics:nil
                                          views:views]

此外,您将能够对布局设置进行分组,混合使用VFL和非VFL约束。 Parus 能够防止常见错误,区分位置参数约束,并提供出色的自动完成支持。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接