Xcode / IB - Autolayout,多个容器视图和滚动视图

时间:2016-07-28 14:45:05

标签: ios swift xcode autolayout interface-builder

我正在尝试使用一些容器视图在Xcode下与IB构建一个接口。

我会尽力解释这个问题:

我有一个包含两个控制器的主场景。第一个位于场景顶部,包含一个" Last Post View",它从Wordpress网站检索最后一个帖子并显示封面图片,帖子的日期和标题。

第二个包含一个集合视图,它可以引导其他视图。

功能和独立,一切似乎都很好。问题是我无法弄清楚如何做这个" stack"具有自动布局功能,适用于纵向和横向模式以及不同的设备。

这是我的故事板

enter image description here

家庭控制器的约束

enter image description here

最后发布视图的约束

enter image description here

收藏视图的约束

enter image description here

..最后,我得到了什么

enter image description here

经过数小时的搜索和尝试后,我发现家庭控制器中包含的滚动视图必须只有一个直接孩子。但我不知道如何设置不同的约束。另外,我总是收到消息:可滚动内容大小不明确" Scroll View"。

我遇到的另一个问题是,当我处于横向模式时,我无法滚动整个视图"。充其量,我只能滚动集合视图(当我可以显示它时)而不是整个屏幕。

(如果我说我使用的是Swift 2,也许可以提供帮助)

有人有建议吗?非常感谢!

非常感谢!

编辑1

我试图运用星程的解决方案,我觉得我的目标非常接近,但我显然错过了一些东西。

这是我的HomeViewController

class HomeViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var containerViewHeightConstrait: NSLayoutConstraint!
    @IBOutlet weak var lastPostContainerView: UIView!
    @IBOutlet weak var scrollContainerView: UIView!
    @IBOutlet weak var mainCollectionContainerView: UIView!

   /*************************/
   /***** VIEW DID LOAD *****/
   /*************************/

   override func viewDidLoad() {

       super.viewDidLoad()

       self.automaticallyAdjustsScrollViewInsets = false

       self.lastPostContainerView.setNeedsDisplay()
       self.mainCollectionContainerView.setNeedsDisplay()

       self.containerViewHeightConstrait.constant = UIScreen.mainScreen().bounds.height - 64

    //END viewDidLoad
    }

    ...

    /********************************/
    /***** SET CONTAINER HEIGHT *****/
    /********************************/

    func needSetContainerHeight( height: CGFloat ) {

        self.containerViewHeightConstrait.constant = height + lastPostContainerView.bounds.height + 200
        self.scrollView.contentSize.height = height + lastPostContainerView.bounds.height + 200

        print( "View Height Constrait \( self.containerViewHeightConstrait.constant )" )
        print( "Scroll View Height \( self.scrollView.contentSize.height )" )

    //END needSetContainerHeight
    }

    ...

...和我的MainCollectionController

class MainCollectionViewController: UICollectionViewController {

    /*************************/
    /***** VIEW DID LOAD *****/
    /*************************/

    override func viewDidLoad() {

        super.viewDidLoad()

        collectionView!.autoresizingMask = [ .FlexibleWidth ]

    //END viewDidLoad
    }

    /****************************************/
    /****************************************/

    /***************************/
    /***** VIEW DID APPEAR *****/
    /***************************/

    override func viewDidAppear( animated: Bool ) {

        super.viewDidAppear( animated )
        ( self.parentViewController as! HomeViewController ).needSetContainerHeight( self.collectionView!.contentSize.height )

    //END viewDidAppear
    }

    ...

如果我很好地理解了提议的内容,那么约束应该是这样的:

(主要)查看

enter image description here

滚动视图

enter image description here

子视图容器

enter image description here

最后发布的容器

enter image description here

收集容器

enter image description here

所有约束的列表

enter image description here

......以及我得到的

肖像

enter image description here

风景

enter image description here

我用不同的额外约束进行了一些测试,我发现我必须告诉Scroll View填充其整个父级以在屏幕上显示某些内容(否则,我只是得到红色背景)。

另一件事是,如果我为Last Post Container和Collection Container之间的空格添加一个约束,那么事情就是"那么"定位但我不能再点击收集的细胞了。但是,如果我不添加此约束,则事情会更加混乱(例如,集合视图与帖子视图重叠),但我可以单击单元格。

不幸的是,屏幕似乎被裁剪,当我旋转屏幕时会有一些差异。但是我想我必须在设备旋转时重新计算高度(我是对的吗?)。屏幕顶部的边距仍然在这里,但并非总是如此:这取决于我启动应用程序的模式以及我做了多少轮换。

我忘了提到的另一件事是最后一篇文章是异步检索的。因此,在显示主屏幕之后显示具有可变尺寸的封面图像。我在AppDelegate中移动了这个 - didFinishLaunchingWithOptions并在通知中心存放了帖子,但不幸的是,还有一些延迟。

有什么建议吗? :)

就像Xingou所说,使用集合视图的标题部分(附件/部分标题)要容易得多。

1 个答案:

答案 0 :(得分:0)

你需要解决以下问题:

  1. 在你的家庭意义上,viewdidload,添加以下代码:

    self.automaticallyAdjustsScrollViewInsets = false 这可以使navagationbar和你之间的红色区域消失。

  2. 修复了Scrollable内容大小不明确的问题" Scroll View": 这是因为scrollview不知道它将显示的内容大小。你需要重置视图的约束(两个容器视图的超级视图),我将其称为scrollcontainerview:

  3. scrollcontainerview.leading = scrollview.leading

    scrollcontainerview.trailing = scrollview.trailing

    scrollcontainerview.top = scrollview.top

    scrollcontainerview.bottom = scrollview.bottom

    scrollcontainerview.width = self.view.width

    scrollcontainerview.height = 603 //我们将通过代码

    更改此值

    现在" Scrollable的内容大小不明确" Scroll View""错误应该消失。

    1. 更改代码中的scrollcontainerview.height: 在你的家庭场景中,将scrollcontainerview.height约束拖动到你的视图控制器中,并将其变为适合屏幕:

      @IBOutlet weak var contianerViewHeightConstrait: NSLayoutConstraint!

       override func viewDidLoad() {
          super.viewDidLoad()
      
          self.automaticallyAdjustsScrollViewInsets = false
          //because we set the height at const 603,but height is different on different device,so we need chang it to the correct value
      
          contianerViewHeightConstrait.constant =       UIScreen.mainScreen().bounds.height - 64
      
      }
      
    2. 现在你可以看到两个容器视图填满了屏幕。

      1. 需要滚动整个内容,而不仅仅是集合视图: 要解决此问题,您需要为scrollview.contentsize.height指定正确的高度。 在你的集合视图控制器:
      2.  override func viewDidAppear(animated: Bool) {
            super.viewDidAppear(animated)
            (self.parentViewController as!    HomeScenceViewController).needSetContainerHeight(self.collectionView.contentSize.height)
        }
        

        然后在HomeScenceViewController中添加一个方法

         // set the containerview and scrollview height
            func needSetContainerHeight(height:CGFloat){
                //the 200 is your first container view's height
                contianerViewHeightConstrait.constant = height + 200
                scrollview.contentSize.height = height + 200
            }
        

        现在您可以滚动整个内容