But sometimes, your graphic designer only gives you a tiny image and:
you don’t want to deal with the button insets in your layout
you still want your users to have a reasonable hit zone
The solution is to override the func hitTest(_:, with:) -> UIView? method of the UIButton, so that it returns said button even if the tap if slightly out of bounds (as long as this matches the 44×44 points rule):
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
It’s sometimes useful to create custom operators to avoid boilerplate code. For example in the following code, we check if a variable is not nil before assigning it to our object:
if let basedOn = basedOn {
story.basedOn = basedOn
}
It would be much better if we could simplify and have this instead:
story.basedOn ?= basedOn
To do that in Swift, we can create an “Optional Assignment” custom operator, as short as ?= here, with a few lines of code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When using custom cells in UICollectionViews, you usually have to go through two things:
registering the cell: usually in the viewDidLoad method, you have to let the collection view know how to create a cell of a given type
dequeue the cell: usually in the collectionView(_:, cellForItemAt:) method, you ask the collection view to dequeue a cell of a given type so that you can configure it and return it
What’s wrong with that?
there is a lot of boilerplate code here
uncertainty around cell identifiers
when dequeuing, you always have to deal with this optional even though there isn’t much you can do if the cell isn’t there
Making registration easier
To make cell registration easier, each cell has to provide two things:
a cell identifier is a string identifying the cell
a cell nib is an object of type UINib used by the collection view to instantiate the cell
I created a protocol that will make more sense later on:
protocol UICollectionViewRegisterable {
static var cellIdentifier: String { get }
static var cellNib: UINib { get }
}
So the cell just needs to conform to this protocol:
To dequeue the cell, the extension is using generics, so we can’t let type inference do the work here, and have to specify the type of the cell for the code to compile:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters