Tuesday, February 7, 2023
Learning Code
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
Learning Code
No Result
View All Result
Home Swift

How to create reusable views for modern collection views?

learningcode_x1mckf by learningcode_x1mckf
September 10, 2022
in Swift
0
How to create reusable views for modern collection views?
74
SHARES
1.2k
VIEWS
Share on FacebookShare on Twitter


2022/02/16

A fast intro to trendy assortment views utilizing compositional structure, diffable knowledge supply and reusable view elements.

UIKit

Reusable views inside a generic cell


All of us like to create custom views for constructing numerous person interface parts, proper? We additionally love to make use of assortment views to show knowledge utilizing a grid or a listing structure. Assortment view cells are customized views, however what if you would like to make use of the very same cell as a view?


Seems that you could present your personal UIContentConfiguration, identical to the built-in ones that you should utilize to setup cells to look like list items. For those who check out the modern collection views sample code, which I extremely suggest, you will see tips on how to implement customized content material configurations in an effort to create your personal cell sorts. There are some things that I do not like about this method. 😕


To begin with, your view has to adapt to the UIContentView protocol, so it’s a must to deal with further config associated stuff contained in the view. I want the MVVM sample, so this feels a bit unusual. The second factor that you simply want is a customized cell subclass, the place you additionally must deal with the configuration updates. What if there was another manner?


Let’s begin our setup by creating a brand new subclass for our future cell object, we’re merely going to supply the standard initialize methodology that I at all times use for my subclasses. Apple typically calls this methodology configure of their samples, however they’re kind of the identical. 😅



import UIKit

open class CollectionViewCell: UICollectionViewCell 
        
    @out there(*, unavailable)
    non-public override init(body: CGRect) 
        tremendous.init(body: body)
        
        self.initialize()
    

    @out there(*, unavailable)
    public required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder) isn not out there")
    
    
    open func initialize() 
        
    



All proper, that is only a primary subclass so we do not have to cope with the init strategies anymore. Let’s create yet another subclass primarily based on this object. The ReusableCell sort goes to be a generic sort, it will have a view property, which goes to be added as a subview to the contentView and we additionally pin the constraints to the content material view.


import UIKit

open class ReusableCell<View: UIView>: CollectionViewCell 
    
    var view: View!

    open override func initialize() 
        tremendous.initialize()

        let view = View()
        view.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(view)
        self.view = view
        
        NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: contentView.topAnchor),
            view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
        ])
    


Through the use of this reusable cell sort, it will be doable so as to add a customized view to the cell. We simply have to create a brand new customized view, however that is fairly a simple activity to do. ✅


import UIKit

extension UIColor 

    static var random: UIColor 
        .init(pink: .random(in: 0...1),
              inexperienced: .random(in: 0...1),
              blue: .random(in: 0...1),
              alpha: 1)
    


class CustomView: View 

    let label = UILabel(body: .zero)

    override func initialize() 
        label.translatesAutoresizingMaskIntoConstraints = false
        label.numberOfLines = 0
        addSubview(label)
        
        
        backgroundColor = .random

        NSLayoutConstraint.activate([
            
            label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
            label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
            label.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
        ])
    



This tradition view has a label, which we are able to pin to the superview with some further padding. You may store all your subviews as strong properties, since Apple goes to deal with the deinit, despite the fact that the addSubview creates a powerful reference, you do not have to fret about it anymore.


If you wish to create a cell that helps dynamic top, you need to merely pin the sting structure constraints, however if you would like to make use of a hard and fast top cell you may add your personal top anchor constraint with a relentless worth. It’s important to set a customized precedence for the peak constraint this fashion the auto structure system will not break and it is going to have the ability to fulfill all the required constraints.



Compositional structure fundamentals


You might also like

The abstract Vapor service factory design pattern

SwiftNIO tutorial – The echo server

Introducing – Vapor cheatsheet – The.Swift.Dev.

The UICollectionViewCompositionalLayout class is a extremely adaptive and versatile structure software that you should utilize to construct trendy assortment view layouts. It has three primary elements that you could configure to show your customized person interface parts in many alternative methods.


You mix the elements by build up from gadgets into a bunch, from teams into a piece, and eventually right into a full structure,
like on this instance of a primary checklist structure:


There are many nice resources and tutorials about this subject, so I will not get an excessive amount of into the main points now, however we’ll create a easy structure that may show full width (fractional layout dimension) gadgets in a full width group, through the use of and estimated top to assist dynamic cell sizes. I suppose that is fairly a standard use-case for many people. We will create an extension on the UICollectionViewLayout object to instantiate a brand new checklist structure. 🙉



extension UICollectionViewLayout 
    static func createListLayout() -> UICollectionViewLayout 
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44))
        let merchandise = NSCollectionLayoutItem(layoutSize: itemSize)
      
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
        let part = NSCollectionLayoutSection(group: group)

        let structure = UICollectionViewCompositionalLayout(part: part)
        return structure
    


Now it’s doable so as to add a collectionView to our view hierarchy contained in the view controller.


class ViewController: UIViewController 

    let collectionView = UICollectionView(body: .zero, collectionViewLayout: .createListLayout())

    override func loadView() 
        tremendous.loadView()

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(collectionView)
        NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: collectionView.topAnchor),
            view.bottomAnchor.constraint(equalTo: collectionView.bottomAnchor),
            view.leadingAnchor.constraint(equalTo: collectionView.leadingAnchor),
            view.trailingAnchor.constraint(equalTo: collectionView.trailingAnchor),
        ])
    

    override func viewDidLoad() 
        tremendous.viewDidLoad()

    


You may as well create your personal auto structure helper extensions, or use SnapKit to rapidly setup your structure constraints. It’s comparatively straightforward to work with anchors, you need to learn my different tutorial about mastering auto layout anchors if you do not know a lot about them.



Cell registration and diffable knowledge supply


Apple has a new set of APIs to register and dequeue cells for contemporary assortment views. It’s price to say that nearly all the pieces we speak about this tutorials is barely out there on iOS14+ so in case you are planning to assist an older model you will not be capable to use these options.


If you wish to be taught extra concerning the subject, I would wish to suggest an article by Donny Wals and there’s a nice, however a bit longer post by John Sundell about trendy assortment views. I am utilizing the identical helper extension to get a cell supplier utilizing a cell registration object, to make the method extra easy, plus we’ll want some random sentences, so let’s add just a few helpers. 💡


extension String 
    static func randomWord() -> String 
        (0..<Int.random(in: 1...10)).map  _ in String(format: "%c", Int.random(in: 97..<123)) .joined(separator: "")
    

    static func randomSentence() -> String 
        (0...50).map  _ in randomWord() .joined(separator: " ")
    



extension UICollectionView.CellRegistration 

    var cellProvider: (UICollectionView, IndexPath, Merchandise) -> Cell 
         collectionView, indexPath, product in
            collectionView.dequeueConfiguredReusableCell(utilizing: self, for: indexPath, merchandise: product)
        
    


Now we are able to use the brand new UICollectionViewDiffableData class to specify our sections and gadgets inside the gathering view. You may outline your sections as an enum, and on this case we’ll use a String sort as our gadgets. There’s a great tutorial by AppCoda about diffable knowledge sources.


Lengthy story quick, you need to make a brand new cell configuration the place now you should utilize the ReusableCell with a CustomView, then it’s doable to setup the diffable knowledge supply with the cellProvider on the cellRegistration object. Lastly we are able to apply an preliminary snapshot by appending a brand new part and our gadgets to the snapshot. You may replace the information supply with the snapshot and the great factor about is it that you could additionally animate the adjustments if you would like. 😍


enum Part 
    case `default`


class ViewController: UIViewController 

    let collectionView = UICollectionView(body: .zero, collectionViewLayout: .createListLayout())
    var dataSource: UICollectionViewDiffableDataSource<Part, String>!
    let knowledge: [String] = (0..<10).map  _ in String.randomSentence() 

    override func loadView() 
        tremendous.loadView()

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(collectionView)
        NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: collectionView.topAnchor),
            view.bottomAnchor.constraint(equalTo: collectionView.bottomAnchor),
            view.leadingAnchor.constraint(equalTo: collectionView.leadingAnchor),
            view.trailingAnchor.constraint(equalTo: collectionView.trailingAnchor),
        ])
    

    override func viewDidLoad() 
        tremendous.viewDidLoad()

        collectionView.delegate = self

        createDataSource()
        applyInitialSnapshot()
    

    func createDataSource() 
        let cellRegistration = UICollectionView.CellRegistration<ReusableCell<CustomView>, String>  cell, indexPath, mannequin in
            cell.view.label.textual content = mannequin
        

        dataSource = UICollectionViewDiffableDataSource<Part, String>(collectionView: collectionView,
                                                                         cellProvider: cellRegistration.cellProvider)
    
    
    func applyInitialSnapshot() 
        var snapshot = NSDiffableDataSourceSnapshot<Part, String>()
        snapshot.appendSections([.default])
        snapshot.appendItems(knowledge)
        dataSource.apply(snapshot, animatingDifferences: true)
    


extension ViewController: UICollectionViewDelegate 

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let merchandise = dataSource.itemIdentifier(for: indexPath)

        print(merchandise ?? "n/a")
    


You continue to must implement a delegate methodology if you would like to deal with cell choice, however happily the diffable knowledge supply has an itemIdentifier methodology to lookup parts inside the information supply.


As you may see it is fairly straightforward to give you a generic cell that can be utilized to render a customized view inside a set view. I imagine that the “official” cell configuration primarily based method is a little more sophisticated, plus it’s a must to write various code if it involves trendy assortment views.


I’ll replace my unique assortment view framework with these new methods for positive. The brand new compositional structure is far more highly effective in comparison with common circulate layouts, diffable knowledge sources are additionally wonderful and the brand new cell registration API can be good. I imagine that the gathering view group at Apple did a tremendous job throughout the years, it is nonetheless certainly one of my favourite elements if it involves UIKit improvement. I extremely suggest studying these trendy methods. 👍






Source link

Share30Tweet19
learningcode_x1mckf

learningcode_x1mckf

Recommended For You

The abstract Vapor service factory design pattern

by learningcode_x1mckf
February 1, 2023
0
The abstract Vapor service factory design pattern

I've written a number of articles about manufacturing unit design patterns on my weblog and this time I might like to speak a couple of particular one, which...

Read more

SwiftNIO tutorial – The echo server

by learningcode_x1mckf
January 27, 2023
0
SwiftNIO tutorial – The echo server

Intoducing SwiftNIO In the event you used a excessive degree net framework, corresponding to Vapor, up to now, you would possibly had some interplay with occasion loops...

Read more

Introducing – Vapor cheatsheet – The.Swift.Dev.

by learningcode_x1mckf
January 23, 2023
0
Introducing – Vapor cheatsheet – The.Swift.Dev.

Out there on Gumroad Thanks for supporting my work by buying the cheatsheet. 🙏 Download now A whole Vapor framework reference for novices. greater than...

Read more

iCloud Programming Tutorial for iOS: An Introduction

by learningcode_x1mckf
January 18, 2023
0
iCloud Programming Tutorial for iOS: An Introduction

Editor’s observe: This week, we work with Ziad Tamim once more to provide you an introduction of iCloud programming. You’ll learn to save and retrieve knowledge from iCloud.On...

Read more

Easy multipart file upload for Swift

by learningcode_x1mckf
January 18, 2023
0
Easy multipart file upload for Swift

I imagine that you've got already heard in regards to the well-known multipart-data add method that everybody likes to add recordsdata and submit type knowledge, but when not,...

Read more
Next Post
Tool shows JavaScript code injected via in-app browser

Tool shows JavaScript code injected via in-app browser

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Related News

Over 83 mln residents inoculated against COVID: West Java govt

Over 83 mln residents inoculated against COVID: West Java govt

September 27, 2022
Java 19 could be big

Java 19 could be big

December 7, 2022
Efficient State Management in JavaScript Apps with Statemanjs

Efficient State Management in JavaScript Apps with Statemanjs

January 11, 2023

Browse by Category

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

RECENT POSTS

  • C++ Is TIOBE's Language Of The Year – iProgrammer
  • JobRunr, the Java Scheduler Library, Released Version 6.0 – InfoQ.com
  • An Introduction to Lodash and Its Benefits for JavaScript Developers – MUO – MakeUseOf

CATEGORIES

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

© 2022 Copyright Learning Code

No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#

© 2022 Copyright Learning Code

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?