如何在所有设备中快速布局每行三个图像

Posted

技术标签:

【中文标题】如何在所有设备中快速布局每行三个图像【英文标题】:How to layout three images per row in all devices swift 【发布时间】:2018-07-01 11:48:08 【问题描述】:

所以基本上我有一个看起来像这样的集合视图布局:

这是一张每行 3 张的图片,像 instagram 一样非常接近。这里的问题是,当我使用 ipad 或像 iphone se 这样的小型手机时,布局会失真。这是它在 ipad 上的样子

集合视图布局代码是这样的:

    func callCustomFlowLayout(collectionView: UICollectionView) 
    let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

    let itemSpacing: CGFloat = 1
    let itemsInOneLine: CGFloat = 3
    flow.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0)
    let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1) //collectionView.frame.width is the same as  UIScreen.main.bounds.size.width here.
    flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
    flow.minimumInteritemSpacing = 1
    flow.minimumLineSpacing = 1

感谢您以后的帮助。我只希望它是每行 3 张图像,并根据设备的大小调整图像大小。

这是我的布局代码

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

    let cellsAcross: CGFloat = 3
    let spaceBetweenCells: CGFloat = 1
    let dim = (collectionView.bounds.width - (cellsAcross - 1) * spaceBetweenCells) / cellsAcross

    return CGSize(width: dim, height: dim)

【问题讨论】:

***.com/a/38028456/1630618 我在那里尝试了答案,但它没有用.. @vacawama 你可能不得不为你的班级采用UICollectionViewDelegateFlowLayout 您的意思是为此设置委托? UICollectionViewDelegateFlowLayout 添加到您的class 定义行。 【参考方案1】:

像这样覆盖 UICollectionView:

class UICollectionViewCustom: UICollectionView 

    public override var bounds: CGRect 
        didSet 
            collectionViewLayout.invalidateLayout()
        
    

这会在 collectionView 调整大小时更新 collectionView 布局。

【讨论】:

您是否将集合视图固定到父视图以根据屏幕宽度调整大小? 是的,它是领先的尾随,底部附加到超级视图 你能分享你的 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 实现吗? 嗨 Adem 感谢您的帮助。我编辑了我的帖子以在实施时添加 sizeforitem 该计算在布局传递之前使用collectionview的初始宽度。当collectionview 大小使用invalidateLayout() 改变时,您需要更新布局。几天前我遇到了同样的问题。上述解决方案应该可以解决。顺便说一句,您是否更新了 nib/storyboard 文件中的 collectionView 类?【参考方案2】:
class CollectionView: UICollectionView 

    private let numberOfCellsPerRow = 3
    private let spacing: CGFloat = 1

    private var flowLayout: UICollectionViewFlowLayout? 
        return collectionViewLayout as? UICollectionViewFlowLayout
    

    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) 
        super.init(frame: frame, collectionViewLayout: layout)
        sharedInit()
        updateItemSize()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        sharedInit()
        updateItemSize()
    

    private func sharedInit() 
        flowLayout?.minimumInteritemSpacing = spacing
        flowLayout?.minimumLineSpacing = spacing
    


    private func updateItemSize() 
        let cellWidth = floor((bounds.width - (CGFloat(numberOfCellsPerRow) - 1) * spacing) / CGFloat(numberOfCellsPerRow))
        flowLayout?.itemSize = CGSize(width: cellWidth, height: cellWidth)
        flowLayout?.invalidateLayout()
    

    override var bounds: CGRect 
        didSet 
            if bounds != oldValue 
                updateItemSize()
            
        
    

结果:

【讨论】:

谢谢!我想通了,因为你所有的答案。显然我的集合视图正在尝试这样做,但没有使用图像视图的约束,因为我没有对单元格内的图像施加约束。

以上是关于如何在所有设备中快速布局每行三个图像的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 约束问题

如何制作一个漂亮的主菜单页面

如何在标题视图 iOS 中创建故事板布局多个视图?

Android:如何设置不同的布局标题和标题栏图标图像

如何根据不同设备类型快速地实现网页界面的响应式布局,只需一句代码立马实现。

如何在所有 iOS 设备上设置自动布局?