13.4 C
Canberra
Monday, October 27, 2025

UICollectionView cells with round pictures plus rotation help


Discover ways to make rounded corners for UIImageView objects wrapped inside assortment view cells, with rotation help.

Round cells inside a group view

Attaining the objective is comparatively simple, however when you don’t know what’s occurring within the background it’s going to be more durable than you’ll assume first. So let’s create a brand new undertaking add a storyboard with a UICollectionViewController, drag a UIImageView contained in the cell, resize it, add some constraints, set the cell identifier.

UICollectionView cells with round pictures plus rotation help

It ought to look one thing just like the picture above. Nothing particular only a easy UI for our instance software. Now seek for some random picture, add it to the undertaking and let’s do some actual coding. First I’ll present you the little trick within the cell subclass.

class Cell: UICollectionViewCell {

    @IBOutlet weak var imageView: UIImageView!

    override var bounds: CGRect {
        didSet {
            layoutIfNeeded()
        }
    }

    override func awakeFromNib() {
        tremendous.awakeFromNib()

        imageView.layer.masksToBounds = true
    }

    override func layoutSubviews() {
        tremendous.layoutSubviews()

        setCircularImageView()
    }

    func setCircularImageView() {
        imageView.layer.cornerRadius = CGFloat(
            roundf(Float(imageView.body.measurement.width / 2.0))
        )
    }
}

Are you able to see it? Sure, you must override the bounds property. As the following step now we have to write down the controller class with some primary knowledge supply for the gathering view and with the right help for the rotation strategies. 🤓

class ViewController: UICollectionViewController {

    override func collectionView(
        _ collectionView: UICollectionView,
        numberOfItemsInSection part: Int
    ) -> Int {
        30
    }

    override func collectionView(
        _ collectionView: UICollectionView,
        cellForItemAt indexPath: IndexPath
    ) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: "Cell", 
            for: indexPath
        ) as! Cell

        cell.imageView.picture = UIImage(named: "Instance.jpg")
        cell.imageView.backgroundColor = .lightGray

        return cell
    }

    override func traitCollectionDidChange(
        _ previousTraitCollection: UITraitCollection?
    ) {
        tremendous.traitCollectionDidChange(previousTraitCollection)

        guard
            let previousTraitCollection = previousTraitCollection,
            traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass ||
            traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass
        else {
            return
        }

        collectionView?.collectionViewLayout.invalidateLayout()
        collectionView?.reloadData()
    }

    override func viewWillTransition(
        to measurement: CGSize, 
        with coordinator: UIViewControllerTransitionCoordinator
    ) {
        tremendous.viewWillTransition(to: measurement, with: coordinator)

        collectionView?.collectionViewLayout.invalidateLayout()

        coordinator.animate(alongsideTransition: { context in

        }, completion: { context in
            collectionView?.collectionViewLayout.invalidateLayout()

            collectionView?.visibleCells.forEach { cell in
                guard let cell = cell as? Cell else {
                    return
                }
                cell.setCircularImageView()
            }
        })
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(
        _ collectionView: UICollectionView,
        format collectionViewLayout: UICollectionViewLayout,
        sizeForItemAt indexPath: IndexPath
    ) -> CGSize {
        .init(
            width: collectionView.body.measurement.width/3.0 - 8,
            top: collectionView.body.measurement.width/3.0 - 8
        )
    }
}

If you’re aware of assortment views, you may ask why am I doing this tutorial? It’s so easy. It simply works, proper? No, really with out the overridden bounds property the instance would look one thing like this on the left aspect. 😢

Circular images

Humorous, huh? The picture on the best aspect is the precise consequence with the overridden bounds, that’s the anticipated habits. Scrolling and rotation goes to be actually unusual when you don’t override bounds and also you don’t reset the cornerRadius property for the seen views. You may ask: however why? 🤔

Layers, springs & struts and a few rationalization

Apple nonetheless has “Springs & Struts” primarily based code within UIKit. Which means that body and certain calculations are taking place within the underlying system and the constraint system is attempting to work laborious as properly to determine the right measures.

“Springs & Struts” must die!

Whereas there may be an init(body:) methodology, or a required init(coder:) these format issues will suck as hell. I actually like Interface Builder, however till we cannot get a superb device to create nice consumer interfaces IB goes to be simply one other layer of doable bugs.

This concern gained’t even be there when you create the cell from code solely utilizing auto format constraints or format anchors! It’s as a result of IB creates the cell primarily based on the body you gave in when you designed your prototype. However when you neglect init(body:) and also you simply create a brand new UIImageView occasion and let auto format do the laborious work, the format system will remedy the whole lot else. Verify this.

class Cell: UICollectionViewCell {

    weak var imageView: UIImageView!

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been carried out")
    }

    override init(body: CGRect) {
        tremendous.init(body: body)

        translatesAutoresizingMaskIntoConstraints = false

        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imageView)
        imageView = imageView

        imageView.topAnchor.constraint(equalTo: topAnchor)
        imageView.bottomAnchor.constraint(equalTo: bottomAnchor)
        imageView.leadingAnchor.constraint(equalTo: leadingAnchor)
        imageView.trailingAnchor.constraint(equalTo: trailingAnchor)
    }

    override func layoutSubviews() {
        tremendous.layoutSubviews()

        imageView.layer.masksToBounds = true
        imageView.layer.cornerRadius = CGFloat(
            roundf(Float(imageView.body.measurement.width/2.0))
        )
    }
}

Clearly you need to write extra code, register your cell class manually contained in the controller class and also you additionally should override the layoutSubviews methodology contained in the cell, nevertheless it’ll work as it’s anticipated. 🙄

collectionView?.register(Cell.self, forCellWithReuseIdentifier: "Cell")

Anyway, after you register the programmatically created cell you’ll have a pleasant manner of displaying round pictures. Utilizing this system is kind of tough, nevertheless it undoubtedly works in each case. You may obtain the instance from The.Swift.Dev. tutorials on GitHub.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles