自动布局,包含动态子视图

时间:2017-02-22 23:57:57

标签: ios iphone xcode layout ios-autolayout

enter image description here

我正在尝试在我的ios 10应用上制作主屏幕,就像上面的照片一样。绿色视图实际上是滚动视图,我为它设置约束以覆盖整个视图。 scrollView上的所有内容我想要滚动。黄色部分是原型细胞的集合视图。此视图中的项目数为6.单元格由照片和标题组成。表格视图是新闻列表(照片+标题)。当在表格视图中启动应用程序时,我加载了10个最新消息以及我收到的其他新闻"加载更多"机制。即使在横向方向上,我也需要适当的app工作。我有定义此布局的问题,因为集合视图和tableView具有动态高度,它们之间的空间必须固定。通常在几乎所有的教程中,人们只修复了scrollView和GridView,在这种情况下,app在纵向方向看起来很好,但我需要更多的灵活性。是否有可能通过自动布局和约束实现这一点,如果是,那么正确的方向是什么

更新:

enter image description here

内容视图 enter image description here

收藏视图

enter image description here

我想要实现的是将集合视图设置为纵向的两列和三行以及横向上的3列和2行。目前我有一个带有滚动的collectionView,但我想要随时扩展,因为collectionView的内容应该由6个突出显示的新闻组成。

在viewDidLoad上,我尝试在正确的位置设置表格视图(在集合视图之后):

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    collection.dataSource = self
    collection.delegate = self

    tableView.delegate = self
    tableView.dataSource = self


   self.view.addConstraint(
        NSLayoutConstraint(
            item: tableView,
            attribute: .top,
            relatedBy: .equal,
            toItem: collection,
            attribute: .bottom,
            multiplier: 1.0,
            constant: 20
    ))



    tableView.frame = CGRect(x: 0,y: collection.collectionViewLayout.collectionViewContentSize.height,width: tableView.frame.width,height: tableView.frame.width ); // set new position exactly

    downloadArticles(offset: "0") {}
}

我想要实现的一个例子是:

enter image description here

目前我有这个:

enter image description here

1 个答案:

答案 0 :(得分:1)

我想我的工作是这样的:

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDataSource, UICollectionViewDelegateFlowLayout, UITableViewDelegate {
    @IBOutlet var collectionView: UICollectionView!
    @IBOutlet var tableView: UITableView!

    @IBOutlet var collectionViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet var tableViewHeightConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "gridCell")

        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "listCell")
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // shrink wrap the collectionView and tableView to fit their content height snuggly
        self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
        self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - CollectionView Methods -
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 6;
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath)

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        cell.backgroundColor = UIColor.lightGray
    }

    func calculateGridCellSize() -> CGSize {
        // -----------------------------------------------------
        // Calculate the size of the grid cells
        // -----------------------------------------------------
        let screenWidth = self.view.frame.size.width
        let screenHeight = self.view.frame.size.height

        var width:CGFloat = 0
        var height:CGFloat = 0

        if(UIDeviceOrientationIsPortrait(UIDevice.current.orientation)) {
            width = screenWidth / 2.0 - 0.5
            height = width
        }
        else {
            width = screenWidth / 3.0 - 1.0
            height = screenHeight / 2.0 - 0.5
        }

        let size:CGSize = CGSize(width: width, height: height)

        return size
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return self.calculateGridCellSize()
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

        coordinator.animate(alongsideTransition: { (context) in
            print("New screen size = \(size.width) x \(size.height)")
            self.collectionView.collectionViewLayout.invalidateLayout()
            self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
            self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
            self.view.layoutIfNeeded()
        }) { (context) in
            self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
            self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
            self.view.layoutIfNeeded()
        }
    }

    // MARK: - TableView Methods -
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10;
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath)

        return cell
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cell.textLabel?.text = "list cell \(indexPath.row)"
    }
}

对于界面布局,我这样做了:

  1. scrollView添加到主视图
  2. 确定scrollview所有四边主视图
  3. contentView添加到scrollView
  4. contentView的所有四边都scrollView contentView
  5. 使scrollView宽度等于collectionView宽度
  6. contentView添加到tableView
  7. contentView添加到collectionView并垂直添加到collectionView
  8. 下方
  9. contentView的左侧,顶部,右侧固定到tableView
  10. contentView的{​​{1}}左侧,右下角和tableView的顶部固定到collectionView的底部
  11. 使collectionView身高667并为NSLayoutConstraint身高创建IBOutlet collectionView(我们稍后可以更新)
  12. 使tableView身高667并为NSLayoutConstraint身高创建IBOutlet tableView(以后再更新)
  13. 使collectionView min项间距1和行间距1
  14. 禁用scrollingEnabled
  15. collectionView
  16. 禁用scrollingEnabled
  17. tableView
  18. collectionView数据源和委托连接到控制器
  19. tableView数据源和委托连接到控制器
  20. 如果有任何帮助,这是布局的屏幕截图。

    layout screenshot

    通常我使用纯代码构建我的UI,你可以复制和粘贴,点击运行按钮,但由于你使用的是Storyboard,我使用Storyboard显示它,希望你可以按照我的布局设置说明进行操作。 / p>

    结果如下:

    portrait screenshot 1 portrait screenshot 2 portrait screenshot 3 landscape screenshot 1 landscape screenshot 2 landscape screenshot 3

    这就是你想要的吗?