【问题标题】:Swift 5 Collection View Layout of Cell and all the items inside the cellCell的Swift 5 Collection View布局和单元格内的所有项目
【发布时间】:2019-12-04 05:56:30
【问题描述】:

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

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

2。我尝试过的

从无数小时的谷歌搜索和 stackoverflow 中,我发现 Collection Views 可能适合这项任务,所以我深入研究了它。 苹果文档缺少一些示例,因此我搜索了教程来帮助我。 在一天结束时,我能够实现类别的水平滚动。 这看起来像这样。

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

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

我不知道如何控制CollectionViewCell 内容的大小和位置。

我假设位置和大小是由我在情节提要中为每个元素设置的约束来处理的,但事实似乎并非如此,现在我迷路了。

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

我对建议持开放态度,我还有一些更结束的问题。

  1. 我的方向正确吗?
  2. 有没有更简单的方法来做到这一点?对于 Web 可能需要 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
        }
    }
}

【问题讨论】:

  • 我建议在底部视图中使用UITableView,并在tableView 的标题视图中使用UICollectionView
  • 您可以使用带有多个部分的表格视图进行类别和发现,并在类别表格视图单元格中创建水平滚动的集合视图
  • 它给了我一个错误提示 - 从 Viewcontroller 到 UICollectionView 的 FeedCollectionView 出口无效。插座不能连接到重复的内容。

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


【解决方案1】:

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

我是这样写的:

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

故事板中的视图控制器将如下所示:

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

有关更多信息,您可以查看演示项目here

【讨论】:

  • 感谢您花时间回答。我现在就试试你的代码。不幸的是,演示项目的链接无效。你介意转发吗?
  • @Taka 立即查看。
  • 上传到Github可以吗?
  • @Taka 现在在 Github 上,因为我忘记公开了。
  • @Okay 我检查了您的解决方案,但我仍然不完全了解如何操作单元格项目的大小。我可以看到您调整了行高,但是如何操作每个单元格项目,例如标签、图像等。在您的示例中,图像并不都具有所需的相同宽度和高度(尽管可能是图像分辨率)
【解决方案2】:

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

答案很简单:约束

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

最后,在处理图像时,您还必须密切注意内容模式。

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

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

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

的属性

然后可能从那里拿走它。

最后,在我的用例中使用 Collection View 和一个项目的提要可能有点矫枉过正,您可能希望按照本文中其他人的建议使用 TableView。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多