ios - Xcode/IB - 自动布局、多个容器 View 和 ScrollView

标签 ios swift xcode autolayout interface-builder

我正在尝试使用一些容器 View 在 Xcode 下构建与 IB 的接口(interface)。

我会尽力解释问题:

我有一个包含两个 Controller 的主场景。第一个,在场景的顶部,包含一个“Last Post View”,它从 Wordpress 网站检索最后一篇文章并显示封面图片、文章的日期和标题。

第二个包含一个 Collection View ,它导致其他 View 。

在功能上和独立上,一切似乎都运行良好。问题是我无法弄清楚如何使用自动布局使这个“堆栈”工作并适合纵向和横向模式以及不同的设备。

这是我的 Storyboard

enter image description here

家庭 Controller 的限制

enter image description here

最后发 TableView 的限制

enter image description here

Collection View 的约束

enter image description here

..最后,我得到了

enter image description here

经过数小时的搜索和尝试,我发现包含在我的 Home Controller 中的 Scroll View 必须只有一个直接子级。但我不知道如何放置不同的约束。另外,我总是收到消息:“ ScrollView ”的可滚动内容大小不明确。

我遇到的另一个问题是,当我处于横向模式时,我无法滚动“整个 View ”。充其量,我只能滚动 Collection 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

subview 容器

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 之间的空间添加了一个约束,那么事情就“很好”地定位了,但我不能再单击集合的单元格了。但是,如果我不添加此约束,事情会更加困惑(例如, Collection View 与帖 subview 重叠),但我可以单击单元格。

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

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

有什么建议? :)

解决方案

就像新狗说的,使用collection view的header section(Accessories/Section Header)要容易得多。

最佳答案

您需要解决以下问题:

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

    self.automaticallyAdjustsScrollViewInsets = false
    这可以使导航栏和您的图片之间的红色区域消失。
  • 修复了“ ScrollView ”的可滚动内容大小不明确:
    这是因为 ScrollView 不知道它会显示的内容大小。您需要重置 View 的约束(两个容器 View 的 super View ),我将其称为滚动容器 View :

  • scrollcontainerview.leading = ScrollView .leading

    scrollcontainerview.trailing = ScrollView .trailing

    滚动容器 View .top = ScrollView .top

    scrollcontainerview.bottom = ScrollView .bottom

    scrollcontainerview.width = self.view.width

    scrollcontainerview.height = 603//我们将通过代码改变这个值

    现在“ ScrollView ”的可滚动内容大小不明确”错误应该消失了。
  • 更改代码中的 scrollcontainerview.height :
    在您的家庭场景中,将 scrollcontainerview.height 约束拖到您的 View Controller 中,并将其更改为适合屏幕:

    @IBOutlet 弱变量 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
    
    }
    

  • 现在你可以看到两个容器 View 填满了屏幕。
  • 需要滚动整个内容,而不仅仅是 Collection View :
    要解决此问题,您需要为 scrollview.contentsize.height 分配正确的高度。
    在你的 Collection View Controller 中:

  •  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
        }
    


    现在你应该可以滚动整个内容

    关于ios - Xcode/IB - 自动布局、多个容器 View 和 ScrollView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38639718/

    相关文章:

    objective-c - Xcode链接错误 "symbol(s) not found for architecture x86_64"

    swift - UITableView 单元格延迟扩展

    ios - 基于在第一个 View Controller 中按下的按钮,xcode 在第二个 View Controller 中打开 url

    swift - 如何从函数中取出纬度和经度的值,以便它们可以在 VC 中的其他任何地方使用?

    ios - 401错误-使用AFNetworking AFHTTPClient和Tastypie进行基本身份验证

    ios - 在 TableView 单元格中通过alamofire解析json数据

    ios - 登录时发生意外故障(基本错误代码 1100)

    ios - 无法使用 XCode 6.0.1 存档构建

    swift - 如何在 Swift 中使用反射获取所有类初始化器

    ios - 我想在下次触发通知时检索