嵌入导航控制器时,UIScrollView的行为有所不同

时间:2015-03-26 00:29:42

标签: ios swift uiscrollview uinavigationcontroller autolayout

在此视图控制器中,我初始化UIScrollView,将其添加到层次结构并在viewDidLoad中添加自动布局约束,并在viewDidLayoutSubviews中添加图像子视图。如果我将它分配到Storyboard中的独立视图,它的行为与预期一样(带图像的方形滚动视图,我可以滚动)。但是,如果我将这个视图嵌入到导航控制器中,不做任何其他更改,我会得到一个填满窗口的黑屏,没有图像。

为什么会发生这种情况,我该如何解决?我已经看到了建议设置内容大小的其他问题[1] [2]。但是,我正在尝试使用autolayout而不是直接设置内容大小。

这是一个最小但完整的例子。再次:使用独立视图,而不是嵌入时:

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

    var scrollView: UIScrollView = UIScrollView(frame: CGRectZero)

    override func viewDidLoad() {
        super.viewDidLoad()

        self.scrollView.delegate = self
        self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
        self.view.addSubview(self.scrollView)
        self.scrollView.maximumZoomScale = 2
        self.scrollView.minimumZoomScale = 1

        self.view.setTranslatesAutoresizingMaskIntoConstraints(false)

        self.configureAutolayout()
    }

    override func viewDidLayoutSubviews() {
        if let x = UIImage(named: "photo.jpg") {
            let y = UIImageView(image: x)
            self.scrollView.addSubview(y)
        }
    }

    func configureAutolayout() {

        var constraint = NSLayoutConstraint(item: self.scrollView,
            attribute: .Leading,
            relatedBy: .Equal,
            toItem: self.view,
            attribute: .Leading,
            multiplier: 1,
            constant: 0)
        self.view.addConstraint(constraint)

        constraint = NSLayoutConstraint(item: self.scrollView,
            attribute: .Trailing,
            relatedBy: .Equal,
            toItem: self.view,
            attribute: .Trailing,
            multiplier: 1,
            constant: 0)
        self.view.addConstraint(constraint)

        constraint = NSLayoutConstraint(item: self.scrollView,
            attribute: .Top,
            relatedBy: .Equal,
            toItem: self.topLayoutGuide,
            attribute: .Bottom,
            multiplier: 1,
            constant: 0)
        self.view.addConstraint(constraint)

        constraint = NSLayoutConstraint(item: self.scrollView,
            attribute: .Height,
            relatedBy: .Equal,
            toItem: self.scrollView,
            attribute: .Width,
            multiplier: 1,
            constant: 0)
        self.view.addConstraint(constraint)

    }

    func viewForZoomingInScrollView(scrollView: UIScrollView!) -> UIView! {
        return self.scrollView.subviews.first as UIView
    }

}

修改

删除以下行修复了一个问题并引入了另一个问题:

self.view.setTranslatesAutoresizingMaskIntoConstraints(false)

带有图像子视图的UIScrollView现在既出现在独立视图中,也出现在导航控制器中。但是,现在嵌入式控制器的滚动视图顶部有一个额外的不需要的空间。我认为TopLayoutGuide是适当的对齐视图 - 事实并非如此吗?

编辑2:

根据此问题[3],通过将self.automaticallyAdjustsScrollViewInsets设置为false来修复插入问题。它没有达到预期的效果。

参考文献:

[1] UIScrollView not scrolling when included into viewcontroller embedded into a navigation controller

[2] UIScrollView scroll not working after pushed with a navigation controller

[3] Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7

2 个答案:

答案 0 :(得分:3)

根据上述两个编辑,通过删除此行来解决问题...

self.view.setTranslatesAutoresizingMaskIntoConstraints(false)

...并添加以下内容:

self.automaticallyAdjustsScrollViewInsets = false

答案 1 :(得分:1)

在iOS10中它对我有用。我正在构建一个项目,我想在导航控制器中添加滚动视图

  1. 首先在导航控制器的视图中添加ScrollView。
  2. 然后从scrollview上的pin添加约束为(0从顶部,0从左侧,0从右侧,0从底部)。
  3. 然后是Scrollview中的另一个Uiview(结构如下图所示)。 Structure of the scrollview and uiview..

  4. 然后在scrollView下的视图上添加禁令(“等宽,等高,垂直居中,容器中水平居中”),如下所示。Adding constraint on view relative to scrollview How Do Add constraints

  5. 另外还从底部和右侧分别添加了一些约束(分别为200和0)。如图片中所示.. Constraints from Pin

  6. 然后添加您要添加​​的内容并从菜单中添加约束。

  7. 点击main.Storyboard中的viewcontroller,然后在viewController中为你的scrollview创建一个@IBOutlet。

  8. 然后将这些行添加到viewDidload()中作为scrollView(在我的情况下)

    let testing : CGFloat = 1000  
    scrollView.contentSize.height = testing
    
  9. 希望这对你有用.. !!!