如何在 iOS 和 Swift 上的收藏夹视图中设置两张照片之间的间隔?

How to set a interval between two photos in UICollecetionView on iOS with Swift?

我想实现照片占满屏幕的效果,并且在相册中滚动照片时,两张照片之间会有间隔,滑动后照片会自动弹回中心.

我设置了minimumLineSpacingisPagingEnabled,但是当我滑动的时候,图片并没有填满整个屏幕,而是左边显示了间距。

有人知道如何实现吗?

代码:

layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 10
view.addSubview(mCollectionView)
mCollectionView.isPagingEnabled = true
mCollectionView.backgroundColor = .white
mCollectionView.register(UINib(nibName: "PhotoDetailCVCell", bundle: nil), forCellWithReuseIdentifier: cvCellIdentifier)
mCollectionView.snp.makeConstraints { (make) in
    make.edges.equalTo(view)
}

目标效果:

静止时:

当我们移动它时:

当前样式仍然是:

这是一种方法 - 它可能适合也可能不适合您的需要...

对于您的单元格布局,请在图像视图的每一侧“填充”5 磅:

当单元格相邻时(流布局设置为 .minimumLineSpacing = 0.minimumInteritemSpacing = 0),视觉结果将看起来 就像有 10 - 图片间距:

接下来,布局集合视图,使其比控制器的视图10 磅:

当您拖动时,单元格之间会出现 10 磅的间距:

.isPagingEnabled = true 会将单元格“对齐”到位:

这是一个完整的示例 - 注意:这只是 示例代码!!

基本单元格 class 带有 UIImageView:

class PhotoDetailCVCell: UICollectionViewCell {
    
    let imgView: UIImageView = {
        let v = UIImageView()
        v.contentMode = .scaleAspectFit
        return v
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        
        contentView.addSubview(imgView)

        // constrain image view
        imgView.snp.makeConstraints { (make) in
            //  top/bottom
            make.top.bottom.equalTo(contentView)
            //  leading/trailing inset by 5-pts
            make.leading.trailing.equalTo(contentView).inset(5.0)
        }

    }
    
}

示例控制器 class:

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
    let cvCellIdentifier: String = "photoCVCell"
    
    var mCollectionView: UICollectionView!
    
    var imgNames: [String] = [
        "p1", "p2", "p3", "p4", "p5",
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let layout = UICollectionViewFlowLayout()
        
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        
        mCollectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        mCollectionView.isPagingEnabled = true
        mCollectionView.backgroundColor = .white

        view.addSubview(mCollectionView)
        
        // respect safe area
        mCollectionView.snp.makeConstraints { (make) in
            // top/bottom equal to safe area
            make.top.bottom.equalTo(view.safeAreaLayoutGuide)
            // leading/trailing equal to safe area inset by -5.0
            //  this makes the collection view 10-pts WIDER than the view
            //  so having 5-pts "spacing" on each side of the cell's imageView
            //  will give the appearance of 10-pts spacing between cells
            make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(-5.0)
        }

        // if you're using a XIB for your cell
        //mCollectionView.register(UINib(nibName: "PhotoDetailCVCell", bundle: nil), forCellWithReuseIdentifier: cvCellIdentifier)
        
        // if you're using code (as in this example) for your cell
        mCollectionView.register(PhotoDetailCVCell.self, forCellWithReuseIdentifier: cvCellIdentifier)
        
        mCollectionView.dataSource = self
        mCollectionView.delegate = self
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        // set collection view itemSize here, since we now know
        //  the frame size of the collection view
        if let layout = mCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.itemSize = mCollectionView.frame.size
        }
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imgNames.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cvCellIdentifier, for: indexPath) as! PhotoDetailCVCell
        
        // try to load the image from Assets
        if let img = UIImage(named: imgNames[indexPath.item]) {
            cell.imgView.image = img
        } else {
            // could not  load image from Assets, so create a systemName image
            if let img = UIImage(systemName: "\(indexPath.item).square.fill") {
                cell.imgView.image = img
            }
        }
        
        // set image view background color if you want to see its frame
        //cell.imgView.backgroundColor = .lightGray

        return cell
    }
    
}

困扰了我好几天,终于找到了解决办法。解决方法很简单。 isPagingEnabled 由collectionView 的frame 决定,所以我们需要让collectionView 的尺寸大于window 的frame。我们可以设置 minimumLineSpacing 并设置 collectionView 的布局,使其向右伸展。然后我们会得到两个单元格之间的间隔,页面就可以正常工作了。

代码如下:

layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 10
view.addSubview(mCollectionView)
mCollectionView.isPagingEnabled = true
mCollectionView.backgroundColor = .white
mCollectionView.register(UINib(nibName: "PhotoDetailCVCell", bundle: nil), forCellWithReuseIdentifier: cvCellIdentifier)
mCollectionView.snp.makeConstraints { (make) in
    make.left.top.bottom.equalToSuperview()
    make.right.equalToSuperview().offset(10)
}