iOS 使用 Autolayout 以编程方式修复 UIScrollView 中子视图的位置
Posted
技术标签:
【中文标题】iOS 使用 Autolayout 以编程方式修复 UIScrollView 中子视图的位置【英文标题】:iOS programmatically fix the position of a subview within UIScrollView with Autolayout 【发布时间】:2014-05-28 18:29:54 【问题描述】:我有一个包含 UIScrollView 的 UIView。 UIScrollView 包含一个 MKMapView 子视图和它正下方的占位符子视图。我想将 MKMapView 固定到屏幕顶部,并允许占位符子视图滑过它并覆盖它。
Apple 表示现在可以使用 Autolayout 完成此操作,但它似乎对我不起作用。下面的代码正确显示了 UIScrollView 及其子视图,但地图仍然与其他所有内容一起滚动。我是否遗漏了一些非常明显的东西?
https://developer.apple.com/LIBRARY/ios/technotes/tn2154/_index.html
请注意,您可以通过在视图和滚动视图的子树之外的视图(例如滚动视图的超级视图)之间创建约束,使滚动视图的子视图看起来浮动(不滚动)在其他滚动内容之上.
UIView .m 文件:
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
// Create scroll view and add to view
UIScrollView *scrollView = [[UIScrollView alloc] init];
[scrollView setBackgroundColor: [UIColor clearColor]];
[scrollView setShowsVerticalScrollIndicator:NO];
[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:scrollView];
// Create map view and add to scroll view
mapView = [[MKMapView alloc] init];
mapView.showsPointsOfInterest = NO;
mapView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:mapView];
// Create a placeholder image to scroll over map view
UIImageView *randomPlaceholderStuff = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"stuff.png"]];
[dividingLine setTranslatesAutoresizingMaskIntoConstraints:NO];
[scrollView addSubview:dividingLine];
// Layouts
NSDictionary *viewArranging = NSDictionaryOfVariableBindings(scrollView, tourMap, randomPlaceholderStuff);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
options:0
metrics:0
views:viewArranging]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
options:0
metrics:0
views:viewArranging]];
UIView *referenceSuperView = scrollView.superview;
[referenceSuperView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mapView(320)]|"
options:0
metrics:0
views:viewArranging]];
[referenceSuperView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mapView(320)]"
options:0
metrics:0
views:viewArranging]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-334-[randomPlaceholderStuff]|"
options:0
metrics:0
views:viewArranging]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[randomPlaceholderStuff(320)]|"
options:0
metrics:0
views:viewArranging]];
return self;
@end
编辑:
jrturton 的回答很到位。这是最终工作的代码:
[self addConstraint:[NSLayoutConstraint constraintWithItem:mapView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:mapView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView.superview attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:mapView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:320.0]];
【问题讨论】:
【参考方案1】:你不能用视觉格式语言做你正在尝试的事情。 |
字符将始终被解释为视图的直接超级视图,因此您不会创建您认为的约束。
您需要使用更长的方法 (constraintWithItem...
) 来创建单独的约束,其中 item1 是您的浮动视图,而 item2 是滚动视图的超级视图。
【讨论】:
【参考方案2】:您可以通过将子视图添加/移动到滚动视图的超级视图来在UIScrollView
上添加浮动子视图,例如:
将您的按钮放置/设置在滚动视图上(不在滚动视图内),如此处快照所示。并且还针对滚动视图的超级视图设置按钮约束(位置)。
这里是参考。每个视图的位置层次结构快照。
【讨论】:
以上是关于iOS 使用 Autolayout 以编程方式修复 UIScrollView 中子视图的位置的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式创建 AutoLayout 约束 (IOS) Xcode 7.0.1
如何使用大于或等于编程 iOS AutoLayout 约束而不使布局模糊?
使用 UIScrollView 和 AutoLayout 以编程方式创建控制器无法正确调整视图大小