UIScrollView with iOS Auto Layout Constraints: Wrong size for subviews(带有 iOS 自动布局约束的 UIScrollView:子视图的大小错误)
问题描述
我正在尝试在代码中生成视图.这是我的视图对象的层次结构
I'm trying to generate a view in code. Here's the hierachy of my view object
- UIScrollView
- UIView
- 界面按钮
ScrollView 应该与窗口大小相同.按钮应尽可能大.我正在使用 iOS 自动布局,所以我所有对象的约束字符串看起来像这样
The ScrollView should be the same size as the window. The button should be as big as possible. I'm using iOS auto layout, so the constraint strings for all of my objects look like this
H:|[object]| V:|[object]|
我还将每个对象的
translatesAutoresizingMaskIntoConstraints
设置为NO
.I've also set
translatesAutoresizingMaskIntoConstraints
toNO
for each object.问题是按钮只获得默认按钮大小.它的父视图对象 (UIView) 仅获得其子视图所需的大小.
The problem is that the button only gets the default button-size. Its parent view object (UIView) only gets the size its subviews need.
红色:UIScrollView/黄色:UIView
如何强制这些视图与滚动视图一样大?
How can I force those views to be as big as the scrollView?
当我使用 UIView 而不是 UIScrollView 时,一切都很好......
When I use a UIView instead of th UIScrollView everything works great...
这里有一些代码:
- (void) viewDidLoad { [super viewDidLoad]; // SCROLL VIEW UIScrollView* scrollView = [UIScrollView new]; scrollView.backgroundColor=[UIColor redColor]; scrollView.translatesAutoresizingMaskIntoConstraints = NO; //CONTAINER VIEW UIView *containerView = [UIView new]; containerView.translatesAutoresizingMaskIntoConstraints = NO; containerView.backgroundColor = [UIColor yellowColor]; [scrollView addSubview:containerView]; // CONSTRAINTS SCROLL VIEW - CONTAINER VIEW [scrollView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|" options:0 metrics:nil views:@{@"containerView":containerView}]]; [scrollView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|" options:0 metrics:nil views:@{@"containerView":containerView}]]; // BUTTON UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.translatesAutoresizingMaskIntoConstraints = NO; [button setTitle:@"I'm way to small" forState:UIControlStateNormal]; [containerView addSubview:button]; // CONSTRAINTS CONTAINER VIEW - BUTTON [containerView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]|" options:0 metrics:nil views:@{@"button":button}]]; [containerView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]|" options:0 metrics:nil views:@{@"button":button}]]; self.view = scrollView; }
更新:我真的不知道,为什么会这样.如果您在 IB 中设置视图,连接插座并在代码中实例化视图,则滚动视图的行为类似于普通视图(垂直反弹).它的 contentSize 计算不正确.更多这里.但是如何正确做呢?
UPDATE: I really don't know, why this is happening. If you set up the view in IB, connect the outlets and instanciate the view in code, the scrollview behaves like a normal view (which bounces vertically). Its contentSize is not calculated correctly. More here. But how to do it correctly?
推荐答案
几点观察:
滚动视图中子视图的约束与其他视图中的约束不同.它们用于设置滚动视图的
contentSize
.(请参阅 TN2154.)那样,您会在滚动视图上扔一堆东西,为里面的东西设置约束,contentSize
会为你计算出来.这是一个非常酷的功能,但它与您在这里尝试做的事情背道而驰.
Constraints for subviews in scroll views don't work like constraints in other views. They're used to set the
contentSize
of the scroll view. (See TN2154.) That way, you throw a bunch of stuff on a scroll view, set the constraints for the stuff inside it, and thecontentSize
is calculated for you. It's very cool feature, but it's antithetical to what you're trying to do here.
更糟糕的是,除非您为按钮的宽度和高度设置明确的约束,否则按钮将根据其内容调整大小.
Worse, buttons will, unless you set an explicit constraint for their width and height of a button, will resize according to their content.
这两个观察结果的最终结果是您现有的约束说(a)将我的容器设置为我的按钮的大小;(b)让我的按钮动态调整自身大小以适应文本的大小;和(c) 根据我的容器大小(也就是按钮的大小)设置我的滚动视图的
contentSize
."The net effect of these two observations is that your existing constraints say "(a) set my container to be the size of my button; (b) let my button resize itself dynamically to the size of the text; and (c) set my scrollview's
contentSize
according to the size of my container (which is the size of the button)."我不清楚业务问题是什么.但是这里有一些限制可以实现我认为您的技术问题是:
I'm unclear as to what the business problem is. But here are some constraints that achieve what I think your technical question was:
- (void)viewDidLoad { [super viewDidLoad]; UIView *view = self.view; UIScrollView *scrollView = [[UIScrollView alloc] init]; scrollView.backgroundColor = [UIColor redColor]; // just so I can see it scrollView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:scrollView]; UIView *containerView = [[UIView alloc] init]; containerView.backgroundColor = [UIColor yellowColor]; // just so I can see it containerView.translatesAutoresizingMaskIntoConstraints = NO; [scrollView addSubview:containerView]; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.translatesAutoresizingMaskIntoConstraints = NO; [button setTitle:@"I'm the right size" forState:UIControlStateNormal]; [containerView addSubview:button]; NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, button, view, containerView); // set the scrollview to be the size of the root view [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:nil views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:nil views:views]]; // set the container to the size of the main view, and simultaneously // set the scrollview's contentSize to match the size of the container [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView(==view)]|" options:0 metrics:nil views:views]]; [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView(==view)]|" options:0 metrics:nil views:views]]; // set the button size to be the size of the container view [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button(==containerView)]" options:0 metrics:nil views:views]]; [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button(==containerView)]" options:0 metrics:nil views:views]]; }
坦率地说,我不了解您的 UI 的商业意图,因为这感觉像是为了实现非常简单的 UI 而对自动布局进行了扭曲.如果您有屏幕大小"的内容(除非您通过按钮分页),我不知道为什么您有滚动视图.我不知道为什么你会有一个包含单个项目的内容视图.我不明白你为什么要使用全屏按钮(当时我只是在根视图上放了一个点击手势,然后就结束了).
Frankly, I don't understand the business intent of your UI, as this feels like a contortion of auto layout to achieve a very simply UI. I don't know why you have a scroll view if you have "screen sized" content in it (unless you were paging through buttons). I don't know why you'd have a content view with a single item in it. I don't understand why you're using a full-screen button (I'd just put a tap gesture on the root view at that point and call it a day).
我假设您有充分的理由这样做,但备份可能是有意义的,询问您想要的用户体验是什么,然后重新解决问题,看看是否有更有效的方法来实现想要的效果.
I'll assume you have good reasons for all of this, but it might make sense to back up, ask what is your desired user experience is, and then approach the problem fresh to see if there's a more efficient way to achieve the desired effect.
这篇关于带有 iOS 自动布局约束的 UIScrollView:子视图的大小错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
- UIView
本文标题为:带有 iOS 自动布局约束的 UIScrollView:子视图的大小
基础教程推荐
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01