如何创建向用户显示一堆卡片的收藏夹视图?

时间:2018-09-08 10:09:01

标签: ios swift uicollectionview

我正在编写iOS纸牌游戏。我想向用户展示他手中的卡片。我寻找的CocoaPods以一种美观的方式完成了此工作,但找不到任何东西,因此我决定自己使用水平UICollectionView创建这样的视图。

以下是一些要求:

  • 集合视图的高度由屏幕的高度动态确定。我这样做有一些自动布局约束
  • 集合视图单元格的高度应等于集合视图的高度。我不知道该怎么做。我只找到this question,这是关于如何使集合视图的高度适合项目的高度的。我想反过来-物品的高度适合收藏视图。
  • 收集视图单元格的宽度应等于其高度* 5 /7。这是卡的W:H比。我想我也可以在约束条件下做到这一点。
  • 每个单元格内都有一个图像视图。图片视图应完全填充整个单元格。

这是我的尝试:

我在情节提要的原型单元中为集合视图和图像视图添加了约束。然后我添加了这段代码。

extension ViewController : UICollectionViewDataSource, UICollectionViewDelegate {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 15
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.addConstraint(NSLayoutConstraint(item: cell, attribute: .height, relatedBy: .equal, toItem: cell, attribute: .width, multiplier: 5.0 / 7.0, constant: 0))
        // here I am just setting all the cells to have the same image for testing purposes
        (cell.viewWithTag(1) as! UIImageView).image = someCardImage
        return cell
    }
}

结果:

似乎只有集合视图的约束起作用。其他一切都不是。我上面以编程方式添加的宽高比约束显然与我不知道的其他约束冲突:

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x604000290810 UICollectionViewCell:0x7fd536610300.height == 0.714286*UICollectionViewCell:0x7fd536610300.width   (active)>",
    "<NSLayoutConstraint:0x600000292390 'UIView-Encapsulated-Layout-Height' UICollectionViewCell:0x7fd536610300.height == 99   (active)>", <---- What is this constraint?
    "<NSLayoutConstraint:0x600000292340 'UIView-Encapsulated-Layout-Width' UICollectionViewCell:0x7fd536610300.width == 68   (active)>" <---- What is this constraint?
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000292390 'UIView-Encapsulated-Layout-Height' UICollectionViewCell:0x7fd536610300.height == 99   (active)>

如UI层次结构所示,图像视图并没有完全填充整个单元格:

enter image description here


如何创建这样的集合视图以满足我的要求?

1 个答案:

答案 0 :(得分:1)

在互联网上浏览了一下之后,我发现了这一点。

显然,collectionView(_:layout:sizeForItemAt:)中有一种称为CollectionViewDelegateFLowLayout的方法。这是我第一次知道这种方法的存在!

如果我重写该方法,则可以根据需要设置单元格的大小:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let height = collectionView.height
    let width = height * 5 / 7
    return CGSize(width: width, height: height)
}

所以我根本不需要编程添加的约束。

对于图像视图的框架问题,我通过反复试验解决了。我在约束的属性检查器中未选中此“相对于边距”选项:

enter image description here

我的猜测是,单元格的“边距”为8像素,因此相对于边距进行设置会留下8个像素的空间。