【问题标题】:How to add an UICollectionViewLayout programmatically?如何以编程方式添加 UICollectionViewLayout?
【发布时间】:2017-07-12 23:50:11
【问题描述】:

我正在尝试以编程方式设置UICollectionViewLayout。我使用的是UICollectionView,也没有使用情节提要,也没有设置它的约束。

我已经按照Ray Wenderlich 的主题教程进行了一些更改以使代码适应 Swift 3(正如 AZCoder2 所做的 https://github.com/AZCoder2/Pinterest)。

由于所有这些示例都使用故事板,我还引入了一些更改来创建 UICollectionView 及其 UICollectionViewLayout

collectionViewLayout = PinterestLayout()
collectionViewLayout.delegate = self
collectionView = UICollectionView.init(frame: .zero, collectionViewLayout: collectionViewLayout)

结果:我什么都看不见。如果我将UICollectionViewLayout 更改为Apple 提供的UICollectionViewFlowLayout,至少我可以看到单元格及其内容。如果我实施一些更改并使用情节提要,一切都会很好,但这不是我想要完成的方式。整个视图是以编程方式制作的,集合视图是其中的一部分。

我错过了什么?这与我实例化UICollectionViewLayout 的方式有关吗?我是否必须注册一些东西(例如,因为我需要注册可重复使用的单元格)?

【问题讨论】:

  • 我假设这段代码在视图控制器中。它是UICollectionViewController 的子类吗?
  • 不,@Jumhyn...这是一个 UIViewController...为什么我需要一个 UICollectionViewController?
  • 谢谢,@SPatel。一年多前,我设法解决了这个问题。不过还是谢谢。我很感激。

标签: swift uicollectionview uicollectionviewlayout pinterest


【解决方案1】:

你要不要创建一个变量来为你创建这样的流布局

var flowLayout: UICollectionViewFlowLayout {
    let _flowLayout = UICollectionViewFlowLayout()

    // edit properties here
    _flowLayout.itemSize = CGSize(width: 98, height: 134)
    _flowLayout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 5)
    _flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal
    _flowLayout.minimumInteritemSpacing = 0.0
    // edit properties here

    return _flowLayout
}

然后你可以通过调用变量来设置它。

self.collectionView.collectionViewLayout = flowLayout // after initializing it another way
// or
UICollectionView(frame: .zero, collectionViewLayout: flowLayout)

【讨论】:

  • 谢谢,Zonily 詹姆斯。实际上,我使用的是自定义布局而不是 UICollectionViewFlowLayout。我的自定义布局和您提到的那个都继承自抽象类UICollectionViewLayout。但是自定义布局需要大量编码才能使其工作。不过,我尝试了您的建议……有些改变。但不起作用。还是谢谢!
  • 您好,我也在 UICollectionViewController 中使用自定义布局,我想在底部显示按钮,那么如何在 UICollectionViewController 中执行此操作? @Leandro
  • @ParthBarot 在这种情况下我认为你应该只使用容器视图。
  • 我没听懂@ZonilyJame 你能举个例子吗?
  • @ParthBarot 你应该使用layoutAttributesForSupplementaryViewlayoutAttributesForDecotarionView。这篇文章是一个很好的起点:objc.io/issues/3-views/collection-view-layouts。也许您可以下载示例项目并尝试理解它。我建议阅读全文。祝你好运。
【解决方案2】:

有可能做我想做的事。基本上,按照我在自己的问题中建议的教程,设置集合视图及其视图布局如下:

collectionViewLayout = PinterestLayout()
collectionViewLayout.delegate = self
collectionView = DynamicCollectionView.init(frame: .zero, collectionViewLayout: collectionViewLayout)

请注意,我使用的是DynamicCollectionView(而不是UICollectionView)。 Apple 不提供此类:我使用this post 中提供的代码制作了自己的课程。

请记住,这种方法是在您使用约束以编程方式创建视图时使用的。 (可能还有其他使用案例)

【讨论】:

    【解决方案3】:

    我认为这会奏效。

    override init(collectionViewLayout layout: UICollectionViewLayout) {
        super.init(collectionViewLayout: layout)
        collectionView?.collectionViewLayout = YourCollectionViewLayout()
    }
    

    【讨论】:

      【解决方案4】:

      我通过以下步骤解决了这个问题:

      1 - 将 UICollectionViewController 更改为内部带有 collectionView 的 UIViewController。

      2 - 在 ViewDidLoad 上,我像往常一样设置代表并添加视图。此外,我实例化了 ViewLayout 并使用它来实例化 CollectionView

        var collectionView: UICollectionView?
      
      
      
      
      override func viewDidLoad() {
      super.viewDidLoad()
      
      navigationController!.isToolbarHidden = true
      
      let layout = MosaicViewLayout()
      layout.delegate = self
      
      collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
      
      guard let collectionView = collectionView else {
        return
      }
      
      view.addSubview(collectionView)
      collectionView.delegate = self
      collectionView.dataSource = self
      collectionView.register(PhotoCell.self, forCellWithReuseIdentifier: "CharacterCell")
      setupCollectionConstraints()
      

      }

      3 - 在 ViewLayout 上,协议保持如下:

      protocol MosaicViewLayoutDelegate:class {
      
      
      func collectionView(_ collectionView: UICollectionView,
                        heightForItemAtIndexPath indexPath: IndexPath) -> CGFloat
      }
      

      不要忘记在类中添加实例

        weak var delegate: MosaicViewLayoutDelegate?
      

      4 - 将代理扩展添加到您的 ViewController

      extension HomeViewImpl: MosaicViewLayoutDelegate {
      func collectionView(_ collectionView: UICollectionView, heightForItemAtIndexPath indexPath: IndexPath) -> CGFloat {
      let random = arc4random_uniform(4) + 1
      return CGFloat(random * 100)
       }
      }
      

      在此处输入代码

      【讨论】:

        猜你喜欢
        • 2015-05-01
        • 2016-11-23
        • 2012-09-16
        • 2014-07-03
        • 2016-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多