Post

Replies

Boosts

Views

Activity

Reply to Is super.init(frame: CGRect) the designated initialiser for a UICollectionViewCell class?
According to the documentation regarding UIView, the init(frame: CGRect) is the designated initialiser for UIView when I instantiate a UIView object programatically. Additional, there's an article on Medium by Abdul Ahad titled "Different types of Init in Swift" (I can't link to this article here unfortunately as the platform rules prohibit it), goes into detail about the various types of initialisers and explains that init(frame: CGRect) is also the designated initialiser for UICollectionViewCell. required init?(coder: NSCoder) on the other hand creates a view from data in an unarchiver. And according to "Passing data by using -required init decoder" also on Medium, we use the decoder in this instance to tell Xcode that we aren't relying on storyboard to instantiate the view (by implementing a fatalError("not using storyboard")) message inside the init?(coder:) method.
Topic: UI Frameworks SubTopic: UIKit
Jul ’25
Reply to Trying to Apply Content Configuration on a UICollectionReusableView
UICollectionReusableView has no property called contentConfiguration. Rather than use UICollectionReusableView as the cell type in the supplementary registration, I used UICollectionViewCell. I also used the API for the UIListContentConfiguration to modify the appearance of the text of the primary and secondary titles to get the larger appearance of the header that I want and the contrast in the text colours of the primary and secondary labels. My code looks like this now: let headerRegistration = UICollectionView.SupplementaryRegistration<UICollectionViewCell>(elementKind: UICollectionView.elementKindSectionHeader) { header, elementKind, indexPath in // Header configuration is handled in the header's init var configuration = UIListContentConfiguration.plainHeader() configuration.text = "Current Emotional State" configuration.textProperties.font = .systemFont(ofSize: 20, weight: .medium) configuration.textProperties.color = .label configuration.secondaryText = "What best describes how you're feeling right now?" configuration.secondaryTextProperties.font = .systemFont(ofSize: 17, weight: .regular) header.contentConfiguration = configuration }
Topic: UI Frameworks SubTopic: UIKit
Jul ’25
Reply to Modifying an associated value of an existing enum instance
Thank you @DTS Engineer , this is what the rest of the enum cases, and its computed properties, look like: enum FilterItem: Hashable { case work(isSelected: Bool) case family(isSelected: Bool) case health(isSelected: Bool) case social(isSelected: Bool) case energetic(isSelected: Bool) case tired(isSelected: Bool) case restless(isSelected: Bool) case heavy(isSelected: Bool) case numb(isSelected: Bool) case calm(isSelected: Bool) case tense(isSelected: Bool) case light(isSelected: Bool) case racing(isSelected: Bool) case focused(isSelected: Bool) case confused(isSelected: Bool) case overthinking(isSelected: Bool) case blank(isSelected: Bool) case reflective(isSelected: Bool) case head(isSelected: Bool) case neck(isSelected: Bool) case chest(isSelected: Bool) case shoulders(isSelected: Bool) case arms(isSelected: Bool) case solarPlexus(isSelected: Bool) case stomach(isSelected: Bool) case lowerAbdomen(isSelected: Bool) case legs(isSelected: Bool) case wholeBody(isSelected: Bool) var filterName: String { switch self { case .work: return "Work" case .family: return "Family/Relationships" case .health: return "Health/Physical Wellbeing" case .social: return "Social" case .energetic: return "Energetic/Alert" case .tired: return "Tired/Fatigued" case .restless: return "Restless/Fidgety" case .heavy: return "Heavy/Weighted Down" case .numb: return "Numb/Tingling" case .calm: return "Calm/Relaxed" case .tense: return "Tense/Tight" case .light: return "Light/Buzzing" case .racing: return "Racing/Fast" case .focused: return "Focused/Clear" case .confused: return "Confused/Foggy" case .overthinking: return "Overthinking/Spiralling" case .blank: return "Blank" case .reflective: return "Reflective/Meditative" case .head: return "Head" case .neck: return "Neck/Throat" case .chest: return "Chest/Heart" case .shoulders: return "Shoulders" case .arms: return "Arms/Hands" case .solarPlexus: return "Solar Plexus" case .stomach: return "Stomach/Gut" case .lowerAbdomen: return "Lower Abdomen/Core" case .legs: return "Legs/Feet" case .wholeBody: return "Whole Body" } } var category: EmotionFiltersViewController.Section { switch self { case .work: return .lifeEvents case .family: return .lifeEvents case .health: return .lifeEvents case .social: return .lifeEvents case .energetic: return .physicalSensations case .tired: return .physicalSensations case .restless: return .physicalSensations case .heavy: return .physicalSensations case .calm: return .physicalSensations case .tense: return .physicalSensations case .light: return .physicalSensations case .numb: return .physicalSensations case .racing: return .mindThoughts case .focused: return .mindThoughts case .confused: return .mindThoughts case .overthinking: return .mindThoughts case .blank: return .mindThoughts case .reflective: return .mindThoughts case .head: return .bodyLocation case .neck: return .bodyLocation case .chest: return .bodyLocation case .shoulders: return .bodyLocation case .arms: return .bodyLocation case .solarPlexus: return .bodyLocation case .stomach: return .bodyLocation case .lowerAbdomen: return .bodyLocation case .legs: return .bodyLocation case .wholeBody: return .bodyLocation } } var isSelected: Bool { switch self { case .work(let isSelected): return isSelected case .family(let isSelected): return isSelected case .health(let isSelected): return isSelected case .social(let isSelected): return isSelected case .energetic(let isSelected): return isSelected case .tired(let isSelected): return isSelected case .restless(let isSelected): return isSelected case .heavy(let isSelected): return isSelected case .calm(let isSelected): return isSelected case .tense(let isSelected): return isSelected case .light(let isSelected): return isSelected case .numb(let isSelected): return isSelected case .racing(let isSelected): return isSelected case .focused(let isSelected): return isSelected case .confused(let isSelected): return isSelected case .overthinking(let isSelected): return isSelected case .blank(let isSelected): return isSelected case .reflective(let isSelected): return isSelected case .head(let isSelected): return isSelected case .neck(let isSelected): return isSelected case .chest(let isSelected): return isSelected case .shoulders(let isSelected): return isSelected case .arms(let isSelected): return isSelected case .solarPlexus(let isSelected): return isSelected case .stomach(let isSelected): return isSelected case .lowerAbdomen(let isSelected): return isSelected case .legs(let isSelected): return isSelected case .wholeBody(let isSelected): return isSelected } } }
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
I have fixed this issue by removing the label from the storyboard and adding programmatically like so: protocol TapLabelCollectionViewCellDelegate: AnyObject { func incrementNumberOfTaps(index: Int) } class TapLabelCollectionViewCell: UICollectionViewCell { var numberOfTapsLabel: UILabel! var delegate: TapLabelCollectionViewCellDelegate? var index: Int! override init(frame: CGRect) { super.init(frame: frame) numberOfTapsLabel = UILabel() numberOfTapsLabel.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(numberOfTapsLabel) NSLayoutConstraint.activate([ numberOfTapsLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), numberOfTapsLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) ]) setUpTapGestureRecognizer() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setUpTapGestureRecognizer() { let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(incrementNumberOfTaps)) print("numberOfTapsLabel", numberOfTapsLabel) numberOfTapsLabel.addGestureRecognizer(tapGestureRecognizer) numberOfTapsLabel.isUserInteractionEnabled = true } @objc func incrementNumberOfTaps() { delegate?.incrementNumberOfTaps(index: index) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
I have implemented the incrementNumberOfTaps(index:) method in the extension of the TapGridViewController: extension TapGridViewController: TapLabelCollectionViewCellDelegate { func incrementNumberOfTaps(index: Int) { cellItems[index].incrementLabelCount() cellItems.append(CellItem(numberOfTaps: 0)) var snapshot = NSDiffableDataSourceSnapshot<Section, CellItem>() snapshot.appendSections([.main]) snapshot.appendItems(cellItems) dataSource.apply(snapshot, animatingDifferences: true) } } And the delegate is assigned in the TapGridViewController as well in the cell registration method: class TapGridViewController: UIViewController { func configureDataSource() { let cellRegistration = UICollectionView.CellRegistration<TapLabelCollectionViewCell, CellItem>(handler: { (cell: TapLabelCollectionViewCell, indexPath: IndexPath, item: CellItem) in cell.delegate = self //assigning the delegate of the cell here. cell.index = indexPath.row cell.numberOfTapsLabel.text = String(item.numberOfTaps) }) }
Topic: UI Frameworks SubTopic: UIKit Tags:
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
Hello, The steps I've gone through to add the label to the Interface Builder are as follows: I dragged the label to my UICollectionViewCell in storyboard. This is the outlet connection that is appearing in the identity inspector: I have added a breakpoint at line 53 setUpTapGestureRecognizer. This breakpoint gets called while the breakpoint at awakeFromNib() does not get called. I've also verified that the outlet in the code is connected to the label because the circle appears filled. Link to project: link.
Topic: UI Frameworks SubTopic: UIKit Tags:
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
There is an extra part in my code: extension TapGridViewController: TapLabelCollectionViewCellDelegate { func incrementNumberOfTaps(index: Int) { cellItems[index].incrementLabelCount() var snapshot = NSDiffableDataSourceSnapshot<Section, CellItem>() snapshot.appendItems(cellItems) dataSource.apply(snapshot, animatingDifferences: true) } } I also moved the cell.delegate = self and the cell.index = indexPath.row to the Cell Registration handler, initially I thought I wasn't able to capture self in the cell registration handler, but upon checking again I can.
Topic: UI Frameworks SubTopic: UIKit Tags:
Jul ’25
Reply to How to Animate Fade of a View Simultaneously with Frame of Another View
It turns out that as I was calling createSearchButtonView() and createSearchBarView() inside of viewDidLayoutSubviews(), the latter method was being called multiple times after I called the UIView.animate block which caused the animation to glitch.
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Feb ’26
Reply to Is super.init(frame: CGRect) the designated initialiser for a UICollectionViewCell class?
According to the documentation regarding UIView, the init(frame: CGRect) is the designated initialiser for UIView when I instantiate a UIView object programatically. Additional, there's an article on Medium by Abdul Ahad titled "Different types of Init in Swift" (I can't link to this article here unfortunately as the platform rules prohibit it), goes into detail about the various types of initialisers and explains that init(frame: CGRect) is also the designated initialiser for UICollectionViewCell. required init?(coder: NSCoder) on the other hand creates a view from data in an unarchiver. And according to "Passing data by using -required init decoder" also on Medium, we use the decoder in this instance to tell Xcode that we aren't relying on storyboard to instantiate the view (by implementing a fatalError("not using storyboard")) message inside the init?(coder:) method.
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Jul ’25
Reply to Documentation for UIListContentConfiguration is incomplete in UIKit
UICollectionViewCell however does have a contentConfiguration property which I can set to be the default content configuration I create. So I think that this is an issue with the documentation that needs to be addressed.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Modifying an associated value of an existing enum instance
Thank you, this is the approach that I've implemented in my code.
Replies
Boosts
Views
Activity
Jul ’25
Reply to Documentation for UIListContentConfiguration is incomplete in UIKit
Done: FB18833847 (Documentation for UIListContentConfiguration is incomplete in UIKit). Thank you @darkpaw
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Trying to Apply Content Configuration on a UICollectionReusableView
UICollectionReusableView has no property called contentConfiguration. Rather than use UICollectionReusableView as the cell type in the supplementary registration, I used UICollectionViewCell. I also used the API for the UIListContentConfiguration to modify the appearance of the text of the primary and secondary titles to get the larger appearance of the header that I want and the contrast in the text colours of the primary and secondary labels. My code looks like this now: let headerRegistration = UICollectionView.SupplementaryRegistration<UICollectionViewCell>(elementKind: UICollectionView.elementKindSectionHeader) { header, elementKind, indexPath in // Header configuration is handled in the header's init var configuration = UIListContentConfiguration.plainHeader() configuration.text = "Current Emotional State" configuration.textProperties.font = .systemFont(ofSize: 20, weight: .medium) configuration.textProperties.color = .label configuration.secondaryText = "What best describes how you're feeling right now?" configuration.secondaryTextProperties.font = .systemFont(ofSize: 17, weight: .regular) header.contentConfiguration = configuration }
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Jul ’25
Reply to Modifying an associated value of an existing enum instance
Thank you @DTS Engineer , this is what the rest of the enum cases, and its computed properties, look like: enum FilterItem: Hashable { case work(isSelected: Bool) case family(isSelected: Bool) case health(isSelected: Bool) case social(isSelected: Bool) case energetic(isSelected: Bool) case tired(isSelected: Bool) case restless(isSelected: Bool) case heavy(isSelected: Bool) case numb(isSelected: Bool) case calm(isSelected: Bool) case tense(isSelected: Bool) case light(isSelected: Bool) case racing(isSelected: Bool) case focused(isSelected: Bool) case confused(isSelected: Bool) case overthinking(isSelected: Bool) case blank(isSelected: Bool) case reflective(isSelected: Bool) case head(isSelected: Bool) case neck(isSelected: Bool) case chest(isSelected: Bool) case shoulders(isSelected: Bool) case arms(isSelected: Bool) case solarPlexus(isSelected: Bool) case stomach(isSelected: Bool) case lowerAbdomen(isSelected: Bool) case legs(isSelected: Bool) case wholeBody(isSelected: Bool) var filterName: String { switch self { case .work: return "Work" case .family: return "Family/Relationships" case .health: return "Health/Physical Wellbeing" case .social: return "Social" case .energetic: return "Energetic/Alert" case .tired: return "Tired/Fatigued" case .restless: return "Restless/Fidgety" case .heavy: return "Heavy/Weighted Down" case .numb: return "Numb/Tingling" case .calm: return "Calm/Relaxed" case .tense: return "Tense/Tight" case .light: return "Light/Buzzing" case .racing: return "Racing/Fast" case .focused: return "Focused/Clear" case .confused: return "Confused/Foggy" case .overthinking: return "Overthinking/Spiralling" case .blank: return "Blank" case .reflective: return "Reflective/Meditative" case .head: return "Head" case .neck: return "Neck/Throat" case .chest: return "Chest/Heart" case .shoulders: return "Shoulders" case .arms: return "Arms/Hands" case .solarPlexus: return "Solar Plexus" case .stomach: return "Stomach/Gut" case .lowerAbdomen: return "Lower Abdomen/Core" case .legs: return "Legs/Feet" case .wholeBody: return "Whole Body" } } var category: EmotionFiltersViewController.Section { switch self { case .work: return .lifeEvents case .family: return .lifeEvents case .health: return .lifeEvents case .social: return .lifeEvents case .energetic: return .physicalSensations case .tired: return .physicalSensations case .restless: return .physicalSensations case .heavy: return .physicalSensations case .calm: return .physicalSensations case .tense: return .physicalSensations case .light: return .physicalSensations case .numb: return .physicalSensations case .racing: return .mindThoughts case .focused: return .mindThoughts case .confused: return .mindThoughts case .overthinking: return .mindThoughts case .blank: return .mindThoughts case .reflective: return .mindThoughts case .head: return .bodyLocation case .neck: return .bodyLocation case .chest: return .bodyLocation case .shoulders: return .bodyLocation case .arms: return .bodyLocation case .solarPlexus: return .bodyLocation case .stomach: return .bodyLocation case .lowerAbdomen: return .bodyLocation case .legs: return .bodyLocation case .wholeBody: return .bodyLocation } } var isSelected: Bool { switch self { case .work(let isSelected): return isSelected case .family(let isSelected): return isSelected case .health(let isSelected): return isSelected case .social(let isSelected): return isSelected case .energetic(let isSelected): return isSelected case .tired(let isSelected): return isSelected case .restless(let isSelected): return isSelected case .heavy(let isSelected): return isSelected case .calm(let isSelected): return isSelected case .tense(let isSelected): return isSelected case .light(let isSelected): return isSelected case .numb(let isSelected): return isSelected case .racing(let isSelected): return isSelected case .focused(let isSelected): return isSelected case .confused(let isSelected): return isSelected case .overthinking(let isSelected): return isSelected case .blank(let isSelected): return isSelected case .reflective(let isSelected): return isSelected case .head(let isSelected): return isSelected case .neck(let isSelected): return isSelected case .chest(let isSelected): return isSelected case .shoulders(let isSelected): return isSelected case .arms(let isSelected): return isSelected case .solarPlexus(let isSelected): return isSelected case .stomach(let isSelected): return isSelected case .lowerAbdomen(let isSelected): return isSelected case .legs(let isSelected): return isSelected case .wholeBody(let isSelected): return isSelected } } }
Replies
Boosts
Views
Activity
Jul ’25
Reply to Modifying an associated value of an existing enum instance
This is not possible, and to resolve this I am going to change the FilterItem into a struct.
Replies
Boosts
Views
Activity
Jul ’25
Reply to Cell Delegate Method Not Being Called
I have implemented a demo app showcasing how to call a cell delegate from the UICollectionView.CellRegistration handler closure, which can be found here: Diffable-Data-Source-With-Cell-Delegate.
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
I have fixed this issue by removing the label from the storyboard and adding programmatically like so: protocol TapLabelCollectionViewCellDelegate: AnyObject { func incrementNumberOfTaps(index: Int) } class TapLabelCollectionViewCell: UICollectionViewCell { var numberOfTapsLabel: UILabel! var delegate: TapLabelCollectionViewCellDelegate? var index: Int! override init(frame: CGRect) { super.init(frame: frame) numberOfTapsLabel = UILabel() numberOfTapsLabel.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(numberOfTapsLabel) NSLayoutConstraint.activate([ numberOfTapsLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), numberOfTapsLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) ]) setUpTapGestureRecognizer() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setUpTapGestureRecognizer() { let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(incrementNumberOfTaps)) print("numberOfTapsLabel", numberOfTapsLabel) numberOfTapsLabel.addGestureRecognizer(tapGestureRecognizer) numberOfTapsLabel.isUserInteractionEnabled = true } @objc func incrementNumberOfTaps() { delegate?.incrementNumberOfTaps(index: index) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
I have implemented the incrementNumberOfTaps(index:) method in the extension of the TapGridViewController: extension TapGridViewController: TapLabelCollectionViewCellDelegate { func incrementNumberOfTaps(index: Int) { cellItems[index].incrementLabelCount() cellItems.append(CellItem(numberOfTaps: 0)) var snapshot = NSDiffableDataSourceSnapshot<Section, CellItem>() snapshot.appendSections([.main]) snapshot.appendItems(cellItems) dataSource.apply(snapshot, animatingDifferences: true) } } And the delegate is assigned in the TapGridViewController as well in the cell registration method: class TapGridViewController: UIViewController { func configureDataSource() { let cellRegistration = UICollectionView.CellRegistration<TapLabelCollectionViewCell, CellItem>(handler: { (cell: TapLabelCollectionViewCell, indexPath: IndexPath, item: CellItem) in cell.delegate = self //assigning the delegate of the cell here. cell.index = indexPath.row cell.numberOfTapsLabel.text = String(item.numberOfTaps) }) }
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Position is Ambiguous for UILabel Warning for label I added programmatically
Thanks @jlilest ! This has resolved the problem.
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
Hello, The steps I've gone through to add the label to the Interface Builder are as follows: I dragged the label to my UICollectionViewCell in storyboard. This is the outlet connection that is appearing in the identity inspector: I have added a breakpoint at line 53 setUpTapGestureRecognizer. This breakpoint gets called while the breakpoint at awakeFromNib() does not get called. I've also verified that the outlet in the code is connected to the label because the circle appears filled. Link to project: link.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
There is an extra part in my code: extension TapGridViewController: TapLabelCollectionViewCellDelegate { func incrementNumberOfTaps(index: Int) { cellItems[index].incrementLabelCount() var snapshot = NSDiffableDataSourceSnapshot<Section, CellItem>() snapshot.appendItems(cellItems) dataSource.apply(snapshot, animatingDifferences: true) } } I also moved the cell.delegate = self and the cell.index = indexPath.row to the Cell Registration handler, initially I thought I wasn't able to capture self in the cell registration handler, but upon checking again I can.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25
Reply to Label I Added in Storyboard Appears nil when I try to Dequeue a Cell Using a Data Source Cell Provider
Why does TapLabelCollectionViewCell need to conform to TapLabelCollectionViewCellDelegate? Isn't it the delegate who needs to conform to this protocol?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jul ’25