如何将2个NSTextView与其间的空格垂直对齐,并使容器视图相应地使用自动布局调整大小

时间:2014-03-14 01:23:19

标签: xcode cocoa autolayout

希望标题清晰。试着拥有以下内容

 --------------------
 | [titleTextView]  |
 |        |         |
 | [detailsTextView]|
 --------------------

使用我尝试的代码,容器调整大小,但titletextView和detailsTextView都放在一起(彼此重叠)。我知道我在(16,0)开始两个但是不应该约束它们正确吗?

我也收到以下错误:Unable to simultaneously satisfy constraints: ("<NSLayoutConstraint:0x60000008fcd0 NSTextView:0x600000134be0.bottom == NSView:0x600000134c80.bottom + 20>", "<NSAutoresizingMaskLayoutConstraint:0x608000093ce0 h=--& v=--& V:[NSTextView:0x600000134be0]-(0)-| (Names: '|':NSView:0x600000134c80 )>")

代码:

//title textView
self.titleTextView = [[NSTextView alloc] initWithFrame:NSMakeRect(16, 0, [self.view frame].size.width - 30, 0)];
[self.titleTextView setEditable:NO];
[self.titleTextView setBackgroundColor:[NSColor clearColor]];
[self.titleTextView setString:@"potentially long text."];
[self.titleTextView setHorizontallyResizable:NO];
[self.titleTextView sizeToFit];

//detail textView
self.detailsTextView = [[NSTextView alloc] initWithFrame:NSMakeRect(16, 0, [self.view frame].size.width - 30, 0)];
[self.detailsTextView setEditable:NO];
[self.detailsTextView setBackgroundColor:[NSColor clearColor]];
[self.detailsTextView setString:@"Very long text."];
[self.detailsTextView setHorizontallyResizable:NO];
[self.detailsTextView sizeToFit];

//Adding to self.view
[self.view addSubview: self.titleTextView];
[self.view addSubview: self.detailsTextView];

[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.titleTextView
                              attribute:NSLayoutAttributeBottom
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.detailsTextView
                              attribute:NSLayoutAttributeTop
                             multiplier:1
                               constant:20]];
[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.titleTextView
                              attribute:NSLayoutAttributeTop
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.view
                              attribute:NSLayoutAttributeTop
                             multiplier:1
                               constant:20]];

[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.detailsTextView
                              attribute:NSLayoutAttributeBottom
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.view
                              attribute:NSLayoutAttributeBottom
                             multiplier:1
                               constant:20]];

2 个答案:

答案 0 :(得分:2)

使用自动布局时,您根本不想考虑帧的布局。约束将决定您的视图框架。

此外,如果您要在代码中创建布局,则必须为要将自动布局引擎应用到的视图调用setTranslatesAutoresizingMaskIntoConstraints:NO

所以,你想要做的事情如下:

UIView* titleTextView = [[UIView alloc] init];
[titleTextView setTranslatesAutoresizingMaskIntoConstraints:NO];
UIView* detailsTextView = [[UIView alloc] init];
[detailsTextView setTranslatesAutoresizingMaskIntoConstraints:NO];

...additional setup stuff...

[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[titleTextView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(titleTextView)]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[detailsTextView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(detailsTextView)]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[titleTextView][detailsTextView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(titleTextView, detailsTextView)]];

如果在代码中工作,我强烈建议您查看visual format language,这样可以在代码中更有效地设置约束,但您也可以使用单独的约束来执行与上面相同的操作。 / p>

答案 1 :(得分:1)

忘掉你以前用rects做的所有事情,并开始思考相对位置。

使用我最喜欢的类别进行自动布局: https://github.com/jrturton/UIView-Autolayout

您可以通过这些简单的约束(我发现比任何官方API解决方案更具可读性和直观性)实现您想要的目标:

[self.titleTextView pinToSuperviewEdges:JRTViewPinLeftEdge|JRTViewPinTopEdge inset:20.0];
[self.detailsTextView pinToSuperviewEdges:JRTViewPinLeftEdge inset:20.0];
[self.detailsTextView pinEdge:NSLayoutAttributeTop toEdge:NSLayoutAttributeBottom ofView:self.titleTextView inset:20];

这会将两个文本视图从左侧20个像素固定,titleTextView从顶部开20个像素,detailsTextView固定在titleTextView下方20个像素。此外,该类别将在每种情况下将约束添加到正确的视图。