Home > other >  How to image setup in UICollectionView in UICollectionViewCell Swift
How to image setup in UICollectionView in UICollectionViewCell Swift

Time:01-27

I am trying to set up images in the horizontal alignment in collectionView, but it's not working properly. Please check the attached screenshot.

View Controller Code:-

import UIKit

class ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {

@IBOutlet weak var texting1: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    
    self.texting1.register(UINib(nibName:"CollectionViewCell1", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell1")
    self.texting1.delegate = self
    self.texting1.dataSource = self
    texting1.backgroundColor = .red
}

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell1", for: indexPath) as! CollectionViewCell1
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.view.frame.width, height: 120)
  }
}

Output:- enter image description here

If we instead use negative constants:

    NSLayoutConstraint.activate([
        red.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0),
        green.leadingAnchor.constraint(equalTo: red.trailingAnchor, constant: -20.0),
        blue.leadingAnchor.constraint(equalTo: green.trailingAnchor, constant: -20.0),
    ])
    

it can look like this:

enter image description here

So we can create a custom UIView subclass that handles all of that for us -- such as this:

class OverlapView: UIView {
    
    public var overlap: CGFloat = -30 { didSet { setNeedsLayout() } }
    
    public var cellViews: [UIView] = [] {
        didSet {
            // clear out any existing subviews
            subviews.forEach { v in
                v.removeFromSuperview()
            }
            cellViews.forEach { v in
                // in case it wasn't set by the caller
                v.translatesAutoresizingMaskIntoConstraints = false
                addSubview(v)
                // center it vertically
                v.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
                // we want the overlap to go from left-to-right
                sendSubviewToBack(v)
            }
            setNeedsLayout()
        }
    }
    
    private var horizontalConstraints: [NSLayoutConstraint] = []
    
    override func layoutSubviews() {
        super.layoutSubviews()

        guard cellViews.count > 0 else { return }

        // de-activate any existing horizontal constraints
        NSLayoutConstraint.deactivate(horizontalConstraints)
        
        var prevView: UIView!
        cellViews.forEach { v in
            // if it's the first one
            if prevView == nil {
                horizontalConstraints.append(v.leadingAnchor.constraint(equalTo: leadingAnchor))
            } else {
                horizontalConstraints.append(v.leadingAnchor.constraint(equalTo: prevView.trailingAnchor, constant: overlap))
            }
            prevView = v
        }
        // constrain last view's trailing
        horizontalConstraints.append(prevView.trailingAnchor.constraint(equalTo: trailingAnchor))

        // activate the udpated constraints
        NSLayoutConstraint.activate(horizontalConstraints)
    }
}

Here's a sample controller demonstrating that:

class OverlapTestVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let testView = OverlapView()
        testView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(testView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            testView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            testView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0),
            testView.heightAnchor.constraint(equalToConstant: 70.0),
            
            // no trailing or width constraint
            //  width will be determined by the number of "cells"
        ])

        // let's add 6 "cells" -- one for each color
        let colors: [UIColor] = [
            .systemRed, .systemGreen, .systemBlue,
            .systemYellow, .systemCyan, .magenta,
        ]
        var cellViews: [UIView] = []
        colors.forEach { c in
            if let img = UIImage(systemName: "person.crop.circle") {
                let imgView = UIImageView(image: img)
                imgView.tintColor = c
                imgView.backgroundColor = .white
                imgView.translatesAutoresizingMaskIntoConstraints = false
                // let's use a 60x60 image view
                imgView.widthAnchor.constraint(equalToConstant: 60.0).isActive = true
                imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor).isActive = true
                // we want "round" views
                imgView.layer.cornerRadius = 30.0
                imgView.layer.masksToBounds = true
                cellViews.append(imgView)
            }
        }

        testView.cellViews = cellViews
        
        // we can change the overlap value here if we don't want to use
        //  our custom view's default
        // for example:
        //testView.overlap = -40.0
        
        // so we can see the framing
        testView.backgroundColor = UIColor(white: 0.9, alpha: 1.0)

    }
    
}

Output looks like this:

enter image description here

(We gave the custom view itself a light gray background so we can see its frame.)

  • Related