【问题标题】:UIScrollView auto layout - content size not set correctlyUIScrollView 自动布局 - 内容大小设置不正确
【发布时间】:2013-06-24 07:47:46
【问题描述】:

我已经看到很多关于这个主题的 Stack Overflow 线程(以及 iOS 6 release notes),但似乎没有一个对我有帮助,或者我无法理解它们。我拥有的是一个大小为 (244, 46) 的滚动视图,我想通过分页滚动到其宽度的两倍。

在我的情节提要中,我已经布置了滚动视图及其子视图(UIButtons 的一行)- 我设置了它们的起源,但删除了所有限制条件,即“将空间引导至 superview”。我将它们替换为“Leading space to button”——连续按钮之间的水平间距。在代码中,我将按钮的 translatesAutoresizingMaskIntoConstraints 设置为 NO。

但是,我无法让滚动视图滚动。它只是弹跳以表明滚动视图边界的右侧有一些东西,只是遥不可及。有什么我做错了,或者我需要其他什么来让它工作吗?

哦,在 Interface Builder 中的最后一个可见按钮(不是行中的最后一个按钮)上还有一个“Trailing space to superview”约束,还有一个“Leading space to @987654326 @" 约束第一个不会被删除的按钮(请参见图像中的紫色约束)。他们烦人地只是突然出现在列表中的不同位置!为什么会发生这种情况,为什么没有正确设置内容大小?

感谢您的宝贵时间!

【问题讨论】:

  • @rob 感谢您的链接,但我仍然不清楚某些事情 - “滚动视图的子视图的约束必须导致要填充的大小”是什么意思?此外,在纯自动布局方法(我在 IB 中这样做)中,它说“确保约束与滚动视图的所有边缘相关联”。这在 IB 中意味着什么 - 将前导和尾随空间固定到 superview?
  • 您必须在滚动视图和它的子视图之间有约束,强制滚动视图在两个维度上都具有非零大小。这个大小将是运行时滚动视图的内容大小;它不会影响滚动视图的框架。
  • 你必须有约束从所有四个滚动视图的边缘连接到它的子视图,以强制它在两个维度上都具有非零大小。如果(例如)您没有从滚动视图的底部边缘对其子视图之一设置任何约束,则不会强制滚动视图的内容高度大于零。
  • @rob 我想我开始明白了。但是当我将前导空间和尾随空间固定到超级视图时,我得到“超级视图的前导空间等于 432”和“超级视图的尾随空间等于 -226”,对吗?我需要对所有子视图执行此操作,还是仅对距离可见区域最远的子视图执行此操作?

标签: iphone ios uiscrollview autolayout


【解决方案1】:

我采纳了@robmayoff 的建议并将我的按钮创建移到了代码中,它奇迹般地奏效了。 (恐怕自动布局对我来说仍然是希腊语,但我以某种方式管理它。)如果将来有人需要创建按钮的滚动列表,这是一种不涉及设置 contentSize 的方法明确地说,如果比 IB 丑一点。

self.toolbarScrollView.translatesAutoresizingMaskIntoConstraints = NO;

NSMutableArray *toolbarItems = [NSMutableArray array];

//Unfortunately, you'll have to set the contentWidth manually - in viewDidLoad
// the frames aren't set yet. 47.0 is the size (38) + margin (9) of one of my
// buttons.
CGFloat x = contentWidth - 47.0;

//This code lets you page the scroll view with more spacing between items on 
//different pages.
int itemCountPerPage = 5;
NSArray *images = @[/*...titles of images...*/];
SEL selectors[10] = {
    //button selectors
};

UIButton *lastButton = nil;

for (int i = 0; i < [images count]; i++)
{
    NSString *imageName = [images objectAtIndex:i];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [button setImage:[UIImage imageNamed:imageName maskedWithColor:[UIColor whiteColor]] forState:UIControlStateNormal];
    button.showsTouchWhenHighlighted = YES;
    if (selectors[i] != NULL)
        [button addTarget:self action:selectors[i] forControlEvents:UIControlEventTouchUpInside];
    [self.toolbarScrollView addSubview:button];
    [toolbarItems addObject:button];

    if (lastButton)
    {
        NSDictionary *dict = NSDictionaryOfVariableBindings(lastButton, button);
        [self.toolbarScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:[lastButton(==38)]-%g-[button(==38)]-%g-|", (i % itemCountPerPage == 0 ? 18.0 : 9.0), x] options:NSLayoutFormatAlignAllCenterY metrics:nil views:dict]];
        [self.toolbarScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-4-[button(==38)]-4-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:dict]];
    }
    else
    {
        NSDictionary *dict = NSDictionaryOfVariableBindings(button);
        [self.toolbarScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-9-[button(==38)]-%g-|", x] options:NSLayoutFormatAlignAllCenterY metrics:nil views:dict]];
        [self.toolbarScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-4-[button(==38)]-4-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:dict]];          
    }

    x -= (i % itemCountPerPage == itemCountPerPage - 1 ? 56.0 : 47.0);  //Extra space to allow for paging
    lastButton = button;
}

我希望这对某人有所帮助,因为它确实给简单的滚动视图带来了很多麻烦!感谢您的帮助。

【讨论】:

  • 你基本上只是在你的答案中转储代码。如果你描述你是如何解决它的,这可能是一个有用的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多