UIScrollView 框架在 iOS 8 和 iOS 7 上的大小不同

Posted

技术标签:

【中文标题】UIScrollView 框架在 iOS 8 和 iOS 7 上的大小不同【英文标题】:UIScrollView frame is a different size on iOS 8 vs iOS 7 【发布时间】:2014-10-23 16:51:52 【问题描述】:

我实现了一个视图控制器,它只显示单个图像并允许用户通过捏合来放大/平移图​​像。它在 ios 7 上运行良好,但在 iOS 8 上,滚动视图的框架大小不同,最终结果是在 iOS 8 上运行时图像在 iPhone 上放大得太远而在 iPad 上缩小得太远。这是因为滚动视图框架的宽度是 600pt,这是它在情节提要中的大小(使用大小类的通用情节提要)。但是我有自动布局约束,应该确保滚动视图伸展以填充可用空间——在 iPad 上应该是 768pt。在 iOS 7 上是这种情况,但在 iOS 8 上不是。

这是设置:在 Interface Builder 中,我有一个 UIViewController,其中包含一个 UIView,其中包含一个带有自动布局约束的 UIScrollView,并带有到超级视图的尾随、前导、底部和顶部空间。然后在viewDidLoad

    UIImage *image = [UIImage imageNamed:@"image"];
    self.imageView = [[UIImageView alloc] initWithImage:image];
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);

    [self.scrollView addSubview:self.imageView];
    self.scrollView.contentSize = image.size;

    #warning Bug here - scroll view frame is 600pt on iOS 8 - should be 768 for iPad
    NSLog(@"scroll view frame wid: %f", self.scrollView.frame.size.width);

我发现如果我将相同的NSLog 放在viewDidAppear 中,则框架的宽度是正确的 768pt。我尝试将该代码移动到viewWillAppear 而不是viewDidLoad,但我得到了相同的结果 - 在viewWillAppear 中也是600。因此,滚动视图正确拉伸以填充显示,但直到它出现在屏幕上之后。在图像出现在屏幕上之前,我需要正确的帧大小,以便计算正确的最小和最大缩放值。

我能做些什么来解决这个问题并确保它适用于 iOS 7 和 8?

【问题讨论】:

当您说“600pt,即它在情节提要中的大小”时,您指的是恒定的大小约束,还是临时的“占位符”内在大小值? @IanMacDonald 当使用通用故事板时,场景的默认大小为 600。由于滚动视图通过自动布局拉伸以填充宽度/高度,默认情况下它也是 600,但它应该拉伸以填充整个视图的大小。 是的,我知道默认大小是 600。我很好奇您的滚动视图是否在我提到的这两个字段中报告了 600,或者它只是在计算的帧字段中。滚动视图是否有不拉伸的超级视图? @IanMacDonald 不,超级视图 (UIView) 会拉伸以填充显示屏,而 UIScrollView 始终保持 600x600。除了前导/尾随/顶部/底部到superview之外没有其他约束,内在内容大小是系统定义的默认值。 其实,不,我错了。 UIScrollView 出现后会拉伸以填充显示屏,但在 viewDidLoad 中它仍然是 600x600。将更新问题。 【参考方案1】:

我已经解决了。出于某种原因,viewDidLoad 在生命周期中太早了,无法在 iOS 8 上获取滚动视图的调整框架,但它在 iOS 7 上再次起作用。viewWillAppear 也太早了,viewWillLayoutSubviews 也是如此。

为了解决这个问题,我只是将需要使用滚动视图框架大小的代码移到了viewDidLayoutSubviews,它最终获得了它出现时的正确大小。

【讨论】:

如果你想避免任何视觉抖动,你总是可以将你的滚动视图设置为隐藏,直到你把它框在viewDidLayoutSubviews中。 非常感谢。我只是花了几个小时试图找出为什么滚动视图中的第一张图片的大小与其他图片不同(因为它们的大小是在稍后的时间点调整的)。【参考方案2】:

我也因类似的问题而苦苦挣扎。我通过以编程方式更改滚动视图内的 contentView 的宽度来解决它。在ViewDidLoad 我调用这个方法

func setupWidthOfContentView()

    let screen = UIScreen.mainScreen().bounds
//        println("Width: \(screen.size.width) Height: \(screen.size.height)")

    var constW = NSLayoutConstraint(item: vwContentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screen.size.width)
    vwContentView.addConstraint(constW)

【讨论】:

以上是关于UIScrollView 框架在 iOS 8 和 iOS 7 上的大小不同的主要内容,如果未能解决你的问题,请参考以下文章

尝试理解 iOS 8 中的 UIScrollView 自动布局

iOS - 将我的 CATextLayer 框架添加到 UIScrollView 的问题

UITableView 有 UIScrollView in Cell 无法在 ios 模拟器 8.3 中滚动

IOS-如何在情节提要上为通用设备的 UIscrollview 设置框架?

iOS:setContentSize 导致我的整个 UIScrollView 框架跳跃

UIScrollview 作为主视图 IOS 8