【问题标题】:Grid layout with CollectionView in Swift在 Swift 中使用 CollectionView 进行网格布局
【发布时间】:2024-01-19 07:25:01
【问题描述】:

我想达到这个结果:

四处搜索我发现这样做的方法可能是使用UICollectionView,所以这没问题,因为 Stack Overflow 上有很多教程和问题。我有 3 个问题:

  1. 我找不到任何关于“分隔符”(分隔所有框的线)的信息。我喜欢它不会水平触摸屏幕边框。是否以编程方式完成?

  2. 为了在所有设备中平均分配空间(水平 3 个框/按钮),我找到了这个答案 answer。这是正确的方法吗?

  3. 对于模糊效果,我找到了这个答案:How to implement UIVisualEffectView in UITableView with adaptive segues

对于TableView,它将是:

if (!UIAccessibilityIsReduceTransparencyEnabled()) {
tableView.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: .Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
tableView.backgroundView = blurEffectView
}

我可以这样做吗?

     @IBOutlet var collectionView: UICollectionView!
    if (!UIAccessibilityIsReduceTransparencyEnabled()) {
    collectionView.backgroundColor = UIColor.clearColor()
    let blurEffect = UIBlurEffect(style: .Light)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    collectionView.backgroundView = blurEffectView
    }

【问题讨论】:

  • 1) 分隔符是装饰视图。所以你需要继承 UICollectionViewFlowLayout 。第一个子类 UICollectionReusableView,然后创建自己的 UICollectionViewLayout。实现 layoutAttributesForElementsInRect 和 layoutAttributesForDecorationViewOfKind:atIndexPath。

标签: ios swift gridview uicollectionview uicollectionviewcell


【解决方案1】:

在从UICollectionViewController 子类化的文件中像这样创建UICollectionViewController

convenience override init() {
    var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(<width>, <height>)
    // Setting the space between cells
    layout.minimumInteritemSpacing = <Space between columns>
    layout.minimumLineSpacing = <Space between rows>
    return (self.init(collectionViewLayout: layout))
}

viewDidLoad 中,您可以像这样设置背景颜色:

self.collectionView.backgroundColor = UIColor.orangeColor()

我猜你可以这样设置背景图片:

self.collectionView?.backgroundColor = UIColor(patternImage: UIImage(named: "image.png")!)

您发现的模糊效果看起来不错。我很难弄清楚它是如何工作的。可能使用backgroundView 属性设置它。

如果我找到答案,我会更新。

更新:

这是一个可以用来模糊细胞的想法。

创建一个从UICollectionViewCell 子类的 cocoa-touch 类,然后将以下代码添加到其中:

convenience override init(frame: CGRect) {
    self.init(frame: frame)
    var blurEffect: UIVisualEffect
    blurEffect = UIBlurEffect(style: .Light)
    var visualEffectView: UIVisualEffectView
    visualEffectView = UIVisualEffectView(effect: blurEffect)
    visualEffectView.frame = self.maskView!.bounds
    self.addSubview(visualEffectView)
}

override func layoutSubviews() {
    super.layoutSubviews()
    self.maskView!.frame = self.contentView.bounds
}

然后在CollectionViewController文件中,在viewDidLoad中,更改这行代码:

self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

UICollectionViewCell.self 更改为&lt;Name of CollectionViewCell file&gt;.self

【讨论】:

  • 在“self.init(frame:frame)”行中出现异常,请帮助(新手!)
  • @CoolBrain,你应该为此打开一个新问题。
  • 异常是由不正确的构造函数引起的。它覆盖视图构造函数,然后调用 self,这意味着它将进入无限递归。要修复它,请将构造函数替换为覆盖 init(frame: CGRect)required init?(coder aDecoder: NSCoder)
  • 不会在单元格和父视图之间添加边距(空格),仅在 - *.com/questions/55659342/…
  • @user924 这是真的,但这就是 OP 想要的。我不确定父级添加单元格之间的关系。
【解决方案2】:

结果:

1) 首先,我认为您需要改变您看待该布局的方式。没有分隔符。只是 UICollectionView 单元格与单元格之间的间距,降低不透明度和一些模糊。

此设置将为您提供接近您发布的图像的内容,您可以稍后根据需要对其进行编辑:

在故事板上转到您的 UICollectionView 的大小检查器。
最小间距-> 对于单元格 = 2,对于行 = 2。
部分插图-> 左 = 7,右 = 7。

2) 我在我的应用程序上使用它来平均划分 3 个单元格的空间。根据您的设置更改它。只需复制/粘贴即可。

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let screenSize: CGRect = UIScreen.mainScreen().bounds
        let screenWidth = screenSize.width
        return CGSize(width: (screenWidth/3)-6, height: (screenWidth/3)-6);
        }
    }

最后一步将两张图片放在 CollectionView 的顶部,分别位于视图的左右两侧,并使宽度等于 7,高度等于 UICollectionView。这些图像应该与单元格具有相同的不透明度/背景。这将使它看起来像您想要的图像。
我希望我的回答对你有用。祝你好运。

【讨论】:

  • 谢谢。我以编程方式添加 UICollectionView。我应该使用insetForSectionAtIndex 函数来添加插图吗?我没有得到相同的结果。此外,您能否详细说明第三个答案?
  • Step 2 现在与 Swift 3 过时了。需要直接使用UICollectionViewFlowLayout*.com/a/43183444/389789
【解决方案3】:

首先我想说的是,你上面的所有结果都可以从UICollectionViewFlowLayout得到,这是UICollectionView的默认布局。

UICollectionViewDelegateFlowLayout 拥有可以满足您要求的所有方法。

  1. flowLayout 有minimumLineSpacingForSectionAtIndexminimumInteritemSpacingForSectionAtIndex 用于提供单元格之间的间距(水平和垂直)。

  2. 这不是在cellForItemAtIndexPath 中提供单元格框架的好方法(就像您提交答案链接一样)。为此,flowLayout 提供了一个代表来调整单元格大小sizeForItemAtIndexPath

  3. 关于第三个问题,是的,您可以使用 UIVisualEffectView 进行模糊处理,但仅在 iOS 8 之后兼容,并且我猜 iPad2 存在问题。但是对于您的问题,我会模糊每个单元格而不是 collectionView 本身(因为单元格间距不模糊)。

【讨论】:

    【解决方案4】:

    我找不到关于“分隔符”(分隔所有框的线)的任何信息。我喜欢它不会水平触摸屏幕边框。是否以编程方式完成?

    是的,它看起来像是在 layer 上渲染的。您应该阅读 Quartz 2D 编程指南以掌握绘图和使用图层。

    为了在所有设备中平均分配空间(水平 3 个框/按钮),我找到了这个答案。这是正确的方法吗?

    这是一个选项,但不会为您提供屏幕截图中的分隔符。

    我会将单元格视图的 backgroundColor 设置为 clearColor,然后将 UICollectionView 的 backgroundView property 设置为包含分隔符和模糊效果的视图。确保 UICollectionView 的 backgroundColor 属性设置为 clearColor。

    关于第三个问题,是的,您可以使用 UIVisualEffectView 进行模糊处理,但仅在 iOS 8 之后兼容并且我猜 iPad2 存在问题。但是对于您的问题,我会模糊每个单元格而不是 collectionView 本身(因为单元格间距不模糊)。

    如果您使用 UICollectionView 的 backgroundView 属性来处理分隔符和模糊,那么您的单元格只需将其 backgroundColor 设置为 clearColor。

    您应该注意,有不止一种方法可以做到这一点,每种方法都有自己的缺点,请选择最适合您的方法。

    【讨论】:

      【解决方案5】:

      我已经为自定义布局创建了这个方法。您可以根据自己的要求修改使用。

      func setCollectionLayout() {
          let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
          layout.sectionInset = UIEdgeInsets(top:0,left:0,bottom:0,right:0)
          layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width/2 - 1, height: 136)
          layout.minimumInteritemSpacing = 1
          layout.minimumLineSpacing = 1
          collectionView.collectionViewLayout = layout
      }
      

      【讨论】:

        最近更新 更多