Some more Xcode in 20 seconds
- Multiple cursors: hold Option and drag to select multiple pieces of text, then write something you want in its place as now there will be multiple cursors.
- View Debugging : select a view and hit Cmd-Shift-D to highlight the view in the navigator.
- Timing test: go to the Report Navigator and select the test you want to check.
- Named Colors: in the Assets catalogue, create a new color set and give it a name to have it available in the storyboard or in code.
- Refactoring Storyboard: woah! This is huge! If the storyboard is getting out of hand for any reason, select the elements and then Editor > refactor Storyboards to extract them without breaking any connection.
- Build Settings: hold down Option and double click or select one and go to the Quick Help in the inspector.
Custom UIButton
Following this video by Sean Allen.
This was quite interesting, not really much to say as it was most refactoring the existing project, but still, it refreshed my mind a bit on UIKit.
Inside the Standard Library – Sequence
– compactMap
Following this video by Paul Hudson.
Here is the definition in the Standard Library:
extension Sequence {
/// Returns an array containing the non-`nil` results of calling the given transformation with each element of this sequence.
/// Use this method to receive an array of non-optional values when your transformation produces an optional value.
/// In this example, note the difference in the result of using `map` and `compactMap` with a transformation that returns an optional `Int` value.
///
/// let possibleNumbers = ["1", "2", "three", "///4///", "5"]
///
/// let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
/// // [1, 2, nil, nil, 5]
///
/// let compactMapped: [Int] = possibleNumbers.compactMap { str in Int(str) }
/// // [1, 2, 5]
///
/// - Parameter transform: A closure that accepts an element of this sequence as its argument and returns an optional value.
/// - Returns: An array of the non-`nil` results of calling `transform` with each element of the sequence.
///
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence and *m* is the length of the result.
@inlinable // protocol-only
public func compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
return try _compactMap(transform)
}
// The implementation of flatMap accepting a closure with an optional result.
// Factored out into a separate functions in order to be used in multiple overloads.
@inlinable // protocol-only
@inline(__always)
public func _compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
var result: [ElementOfResult] = []
for element in self {
if let newElement = try transform(element) {
result.append(newElement)
}
}
return result
}
}
Brilliant, right?!
Inside the Standard Library – Sequence
– flatMap
//===----------------------------------------------------------------------===//
// flatMap()
//===----------------------------------------------------------------------===//
extension Sequence {
/// Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.
/// Use this method to receive a single-level collection when your transformation produces a sequence or collection for each element.
/// In this example, note the difference in the result of using `map` and `flatMap` with a transformation that returns an array.
/// let numbers = [1, 2, 3, 4]
/// let mapped = numbers.map { Array(repeating: $0, count: $0) }
/// // [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
///
/// let flatMapped = numbers.flatMap { Array(repeating: $0, count: $0) }
/// // [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
///
/// In fact, `s.flatMap(transform)` is equivalent to
/// `Array(s.map(transform).joined())`.
///
/// - Parameter transform: A closure that accepts an element of this
/// sequence as its argument and returns a sequence or collection.
/// - Returns: The resulting flattened array.
///
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence
/// and *m* is the length of the result.
@inlinable
public func flatMap<SegmentOfResult: Sequence>(
_ transform: (Element) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.Element] {
var result: [SegmentOfResult.Element] = []
for element in self {
result.append(contentsOf: try transform(element))
}
return result
}
}
Swift on Sundays episode 5 – iMultiply
This was a great stream indeed.
As Paul is soon publishing a book on his Swift on Sundays events I will not cover the ins and outs of this project, also because iti s quite straightforward.
Working on my app
I now have a UIImage
displayed as the viewForHeaderInSection
of the first section of a table view. It is a very simple method implementation but the view is stretching and occupying the whole width of the screen. I would like it to have some insets so I thought about going down the Core Graphics route but something is not working. It seems that I should create a CGRect
and then another CGRect
inside to host the image. I will try again tomorrow.
[more than a day later]
I managed to solve this thanks to some help from the Hacking with Swift Slack community. One idea was to create a custom subclass of the header view, but I didn’t feel comfortable with it, nor did I want to venture in the uncharted territory of XIBs.
I accepted the fact that the first section would not have a title anymore — by now at least — and I created an UIView
, then the UIImageView
based on the flag image, set its TAMIC to false and then added it as a subview to the view. At this point it was enough to add a few constraints and to return the view.
I don’t know what had gone wrong before but such is life.
Now my app in its basic functionality is pretty well finished and I can start fiddling around adding polishing effects and extra functionalities.
That’s it for today!
Thank you for reading!
If you like what I’m doing here please consider liking this article and sharing it with some of your peers. If you are feeling like being really awesome, please consider making a small donation to support my studies and my writing (please appreciate that I am not using advertisement on my articles).
If you are interested in my music engraving and my publications don’t forget visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus, ScoreExchange and on Apple Books).
You can also support me by buying Paul Hudson’s books from this Affiliate Link.
Anyways, thank you so much for reading!
Till the next one!