单元格及其内部所有项目的Swift 5集合视图布局

时间:2019-12-04 05:56:30

标签: swift uicollectionviewcell uicollectionviewlayout xcode11.2 swift5.2

我是IOS开发的新手,我只是想弄湿我的脚。在过去的几天中,我一直在尝试着围绕如何在swift中嵌入水平和垂直滚动以获取视图。 人们似乎提到并使用的一件事是收藏视图。我一直在尝试学习如何正确使用它们并构建您可以在下面的Swift中看到的图片。

Goal or what I'm trying to build in Swift

浏览类别标签下,有一个允许水平滚动的容器,即类别容器。 标签 discover 下有另一个容器,该容器应允许垂直滚动,即feed容器(类似于instagram,Airbnb,Pinterest等)

2。我尝试过的

经过无数小时的谷歌搜索和堆栈溢出,我发现集合视图可能适合此任务,因此我进行了深入研究。 苹果文档缺少一些示例,因此我搜索了一些教程来帮助我。 最终,我能够实现类别的水平滚动。 看起来像这样。 Horizontal Scroll for categories

到目前为止一切顺利! 当我尝试添加下一个集合滚动视图(提要的垂直视图)时,问题实际上就开始了。 添加提要集合后,屏幕将如下所示。

Feed Collection View

那我到底是什么问题? 好吧,我的问题是,尽管我在情节提要板中为UIIMage视图设置了约束,以填充整个内容视图,但仍会看到其他内容。 我想知道如何完美控制UIImageView和其他任何元素的大小和形状。 为了简单起见,我省略了诸如星号,用户名等内容。 但是当我尝试实现这一目标时,项目就囊括了一切。

我无法确定如何控制CollectionViewCell内容的大小和位置。

我以为我在情节提要板中为每个元素设置的约束都考虑到了位置和大小,但事实并非如此,现在我迷路了。

我看到一些帖子,其中有人提到 UICollectionViewLayoutAttributes ,但我只是不知道该如何将其合并到我的项目中。

我愿意接受建议,并且还有其他一些结题。

  1. 我朝着正确的方向前进吗?
  2. 是否有更简单的方法来做到这一点?网络可能需要15行代码,似乎是很多代码。

提前谢谢

Github:https://github.com/Taharcca/LayoutChallenge.git

代码段

        import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var categoriesCollectionView: UICollectionView!
    @IBOutlet weak var feedCollectionView: UICollectionView!

    let categories = Category.load() // Load data
    let feeds = Feed.load()
    override func viewDidLoad() {
        super.viewDidLoad()
        categoriesCollectionView.dataSource = self
        categoriesCollectionView.delegate = self
        feedCollectionView.dataSource = self
        feedCollectionView.delegate = self
        // Do any additional setup after loading the view.
    }
}

extension ViewController: UICollectionViewDelegate {
    // Not sure when to use this
}

// Diese Erweiterung legt die Datenquelle einer Collection View fest
extension ViewController: UICollectionViewDataSource {
    // Wie viele Reihen?
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    // Wie viele Objekete soll es geben?
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == categoriesCollectionView {
            return categories.count
        }
        else {
            return feeds.count
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == categoriesCollectionView {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCollectionViewCell", for: indexPath) as! CategoryCollectionViewCell
            let category = categories[indexPath.item]
            cell.category = category
            return cell
        }
        else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeedCollectionViewCell", for: indexPath) as! FeedCollectionViewCell
            let feed = feeds[indexPath.item]
            cell.feed = feed
            return cell
        }
    }
}

// Größe der Zellen...Sehr intuitiv..... Danke Apple
extension ViewController: UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:
            UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            if collectionView == categoriesCollectionView {
                return CGSize(width: 150, height: 75) // Collection View size right?
            }
            else {
                return CGSize(width: 374, height: 494)
            }

}

}

    import UIKit

class FeedCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var backgroundImage:UIImageView!

    var feed:Feed! {
        didSet {
            self.update()
        }
    }
    func update() {
        if let feed = feed {
            backgroundImage.image = feed.image
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以通过在UITableView中添加UICollectionView来轻松实现tableHeaderView

我的写法如下:

import UIKit

class DemoWithTableViewController: UIViewController {

    //MARK:- @IBOutlet
    @IBOutlet weak var categoriesCollectionView: UICollectionView!
    @IBOutlet weak var tblFeed: UITableView!

    //MARK:- Properties
    let categories = Category.load()
    let feeds = Feed.load()

    override func viewDidLoad() {
        super.viewDidLoad()

        setupUI()
    }
}

//MARK:- Setup UI
extension DemoWithTableViewController {

    func setupUI() {

        categoriesCollectionView.dataSource = self
        tblFeed.dataSource = self
        tblFeed.delegate = self
    }
}

//MARK:- UICollectionViewDataSource
extension DemoWithTableViewController: UICollectionViewDataSource {

    // Wie viele Objekete soll es geben?
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCollectionViewCell", for: indexPath) as! CategoryCollectionViewCell
        let category = categories[indexPath.item]
        cell.category = category
        return cell
    }
}

//MARK:- UITableViewDataSource
extension DemoWithTableViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return feeds.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tblFeed.dequeueReusableCell(withIdentifier: "FeedTableViewCell") as! FeedTableViewCell
        let feed = feeds[indexPath.item]
        cell.feed = feed
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 360
    }
}

情节提要中的视图控制器如下所示:

enter image description here

您的结果将是上面的代码:

enter image description here

有关更多信息,请查看演示项目here

答案 1 :(得分:0)

经过更多的Stackoverflowing并观看了其他教程之后,我终于找到了解决问题的真正方法。

答案很简单:约束

从情节提要中创建所有内容时,必须确保设置正确的约束。 这包括尾随,顶部等的约束。 更重要的是宽度和高度。

最后,使用图像时,您还必须密切注意内容模式。

根据您选择的内容模式,您可能会得到有趣的结果。

最后,使用情节提要时,Apple的Collection View可以按预期工作。 项目布局是使用情节提要设置的。

如果需要,可以通过扩展以下协议来更改单元格项目的布局:UICollectionViewDelegateFlowLayout。 您也可以设置一个引用 UICollectionFlowLayout

的属性

然后可能从那里拿走。

最后,在我的用例中将Collection View与某项Feed一起使用可能是过大的选择,您可能希望按照本文中其他人的建议使用TableView。