我以编程方式构建视图并使用autolayout,根本没有界面构建器。在自定义ScrollView控制器中,我添加了UILabel和UIButton作为子视图。我想将标签对齐到屏幕左侧,按钮位于屏幕右侧。出于某种原因,我的按钮仅对齐我的滚动视图的左侧。我已经减少了我的代码,因此只有这两个标签,我无法理解为什么它不会与右边对齐。
HWScrollViewController.m(我如何初始化主滚动视图)
- (void)loadView
{
self.scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.scrollView.delegate = self;
self.view = self.scrollView;
}
HWListingDetailViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *priceLabel = [[UILabel alloc] init];
UIButton *favouriteButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
[priceLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[favouriteButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[priceLabel setText:@"$125.00"];
[favouriteButton setTitle:@"Add to Favourites" forState:UIControlStateNormal];
[self.view addSubview:priceLabel];
[self.view addSubview:favouriteButton];
[self.view addConstraints:@[
[NSLayoutConstraint constraintWithItem:priceLabel
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0],
[NSLayoutConstraint constraintWithItem:priceLabel
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1
constant:5],
[NSLayoutConstraint constraintWithItem:favouriteButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0],
[NSLayoutConstraint constraintWithItem:favouriteButton
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1
constant:5],
}
如您所见,绿色价格标签已正确对齐,但红色按钮远离屏幕左侧。 (我给了它5个像素的偏移量来显示它的位置。)那么,为什么scrollview的右侧实际上是左侧?如何正确对齐屏幕右侧?我哪里做错了?这让我发疯了!
感谢您的帮助!
最终布局图片: 我希望最终的布局是这样的:
如果旋转到横向,我希望它看起来像这样:
答案 0 :(得分:8)
约束的数量不是问题。 UILabel
和UIButton
都将根据intrinsicContentSize
确定其大小,因为您对该位置有约束,所以它应该具有布局所需的所有信息。
但是,当谈到自动布局时,UIScrollViews
会以独特的方式运行。最佳描述来自此technical note。有两个选项可供选择,包括示例,但下面是每个选项的摘要。
混合方法
您只需向UIView
添加UIScrollView
,然后在UIView
中添加和定位所有子视图。这需要您手动设置frame
的{{1}}和UIView
上的contentSize
。
这可能是您尝试实现的布局最容易使用的。但是,如果UIScrollView
可以更改,则必须手动计算并更新大小。
纯自动布局方法
此选项使用您的自动布局约束来确定contentSize
的{{1}}。这需要约束到UIScrollView的所有四个边缘,并且不能依赖于UIScrollView的大小。
此选项使用起来比较困难,因为您需要确保有足够的约束。在您的情况下,您将遇到问题,因为contentSize
的顶部和底部没有约束,并且没有可用于确定UIScrollView
宽度的约束。但是,当您必须处理动态内容时,此选项会很棒,因为它会根据需要调整UIScrollView
的大小。
就个人而言,我会选择Pure Auto Layout Approach。它能够处理动态内容大小,使额外的约束设置值得。
如果你发布了你想要的最终版面,我会更新我的回答以反映这一点。
<强>更新强>
根据您发布的图像,这是我使用纯自动布局方法组织子视图的方式。主要区别在于UIScrollView
现在是UIViewControllers视图的子视图。
contentSize
scrollView需要约束,因此它的边距是self.view的0px。
contentView需要约束,因此它的边距是scrollView的0px,宽度等于self.view。因此,当您旋转设备时,scrollView的UIScrollView
会更新。
接下来,只需按照您想要的方式放置所有图像和标签即可。标签需要左右约束,以便计算其高度。需要注意的重要事项是contentView将根据其子视图的约束来确定其高度,因此您需要约束“链接”contentView的顶部和底部。一个simeple示例看起来像这样。
答案 1 :(得分:0)
您没有足够的按钮限制。实际上,你也没有足够的标签限制,但这并不一定会阻止你的按钮对齐屏幕右侧。
您始终必须具有约束,这些约束指定视图在水平和垂直方向的行为方式。通常这意味着至少有四个约束 - x,y,宽度和高度。如果你不这样做,iOS会为你猜测,并且可能会出错。您可能会注意到在Xcode控制台中会抛出一些警告。
对于这个问题,它实际上取决于您希望视图看起来的 ,但最简单的解决方案是只为按钮设置宽度约束。你可以这样做:
[NSLayoutConstraint constraintWithItem:favouriteButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:64.0];
其中64.0f如果按钮的宽度。
如果您希望按钮位于标签的右侧并共享相同的宽度(即每个按钮占据屏幕的50%),您可以这样做:
[NSLayoutConstraint constraintWithItem:favouriteButton
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:priceLabel
attribute:NSLayoutAttributeTrailing
multiplier:1.0f
constant:0.0f];
[NSLayoutConstraint constraintWithItem:favouriteButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:priceLabel
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f];
以上两个约束都是将标签的后缘设置为按钮的前沿,然后表示两个视图的宽度必须相同。
您还应该为两个视图(或顶部和底部约束)添加高度约束。我知道你有一个垂直居中约束,但是没有指定它的大小。 iOS可能会按内容高度进行处理,但很可能会在控制台中发出警告。