diff --git a/README.md b/README.md index aa036ef..0a9a1d9 100644 --- a/README.md +++ b/README.md @@ -8,63 +8,93 @@ Here's list of Swift tips & tricks with all additional sources (playgrounds, ima ## 📃 Table of contents -[#57 Render HTML within a `UILabel`](https://github.com/Luur/SwiftTips#57-render-html-within-a-uilabel)
-[#56 Custom `Error` by adopting `LocalizedError` protocol](https://github.com/Luur/SwiftTips#56-custom-error-by-adopting-localizederror-protocol)
-[#55 'Result' type without value to provide](https://github.com/Luur/SwiftTips#55-result-type-without-value-to-provide)
-[#54 Given, When, Then](https://github.com/Luur/SwiftTips#54-given-when-then)
-[#53 `sut` and test lifecycle](https://github.com/Luur/SwiftTips#53-sut-and-test-lifecycle)
-[#52 Point on circle perimeter](https://github.com/Luur/SwiftTips#52-point-on-circle-perimeter)
-[#51 `zip()` function](https://github.com/Luur/SwiftTips#51-zip-function)
-[#50 StackView custom spacing](https://github.com/Luur/SwiftTips#50-stackview-custom-spacing)
-[#49 Named UIColor](https://github.com/Luur/SwiftTips#49-named-uicolor)
-[#48 `Result` error handling](https://github.com/Luur/SwiftTips#48-result-error-handling)
-[#47 Generics: Type parameters](https://github.com/Luur/SwiftTips#47-generics-type-parameters)
-[#46 Generics: Basics](https://github.com/Luur/SwiftTips#46-generics-basics)
-[#45 UserDefaults during testing](https://github.com/Luur/SwiftTips#45-userdefaults-during-testing)
-[#44 Additional Info to #38 Protocols: Optional methods](https://github.com/Luur/SwiftTips#44-additional-info-to-38-protocols-optional-methods)
-[#43 Responsible view controller for particular view](https://github.com/Luur/SwiftTips#43-responsible-view-controller-for-particular-view)
-[#42 Move between textfields](https://github.com/Luur/SwiftTips#42-move-between-textfields)
-[#41 Autogenerated `allCases` property for your `enum` (Swift 4.2)](https://github.com/Luur/SwiftTips#41-autogenerated-allcases-property-for-your-enum-swift-42)
-[#40 Protocols: Class-only](https://github.com/Luur/SwiftTips#40-protocols-class-only)
-[#39 Protocols: Inheritance and composition](https://github.com/Luur/SwiftTips#39-protocols-inheritance-and-composition)
-[#38 Protocols: Optional methods](https://github.com/Luur/SwiftTips#38-protocols-optional-methods)
-[#37 Protocols: Naming](https://github.com/Luur/SwiftTips#37-protocols-naming)
-[#36 Property observers, getter/setter and lazy are mutually exclusive](https://github.com/Luur/SwiftTips#36-property-observers-gettersetter-and-lazy-are-mutually-exclusive)
-[#35 Prepare Alamofire standalone functions to unit-testing](https://github.com/Luur/SwiftTips#35-prepare-alamofire-standalone-functions-to-unit-testing)
-[#34 Sort array of objects with multiple optional criteria](https://github.com/Luur/SwiftTips#34-sort-array-of-objects-with-multiple-optional-criteria)
-[#33 Remove object from array](https://github.com/Luur/SwiftTips#33-remove-object-from-array)
-[#32 Delegate naming](https://github.com/Luur/SwiftTips#32-delegate-naming)
-[#31 Run, Playground, run!](https://github.com/Luur/SwiftTips#31-run-playground-run)
-[#30 `DispatchGroup` usage](https://github.com/Luur/SwiftTips#30-dispatchgroup-usage)
-[#29 Remove duplicates](https://github.com/Luur/SwiftTips#29-remove-duplicates)
-[#28 Debugging: View Debugging](https://github.com/Luur/SwiftTips#28-debugging-view-debugging)
-[#27 Debugging: Breakpoints](https://github.com/Luur/SwiftTips#27-debugging-breakpoints)
-[#26 Debugging: Asserts](https://github.com/Luur/SwiftTips#26-debugging-asserts)
-[#25 Debugging: Log functions](https://github.com/Luur/SwiftTips#25-debugging-log-functions)
-[#24 Update `UIView` content with animation](https://github.com/Luur/SwiftTips#24-update-uiview-content-with-animation)
-[#23 Observe MOC changes](https://github.com/Luur/SwiftTips#23-observe-moc-changes)
-[#22 Split `String` into words](https://github.com/Luur/SwiftTips#22-split-string-into-words)
-[#21 Comparing tuples](https://github.com/Luur/SwiftTips#21-comparing-tuples)
-[#20 How to detect that user stop typing](https://github.com/Luur/SwiftTips#20-how-to-detect-that-user-stop-typing)
-[#19 Left/rigth text offset inside `UITextField`](https://github.com/Luur/SwiftTips#19-leftrigth-text-offset-inside-uitextfield)
-[#18 Common elements in two arrays](https://github.com/Luur/SwiftTips#18-common-elements-in-two-arrays)
-[#17 Apply gradient to Navigation Bar](https://github.com/Luur/SwiftTips#17-apply-gradient-to-navigation-bar)
-[#16 Get next element of array](https://github.com/Luur/SwiftTips#16-get-next-element-of-array)
-[#15 Split array by chunks of given size](https://github.com/Luur/SwiftTips#15-split-array-by-chunks-of-given-size)
-[#14 Transparent/Opaque Navigation Bar](https://github.com/Luur/SwiftTips#14-transparentopaque-navigation-bar)
-[#13 Group objects by property](https://github.com/Luur/SwiftTips#13-group-objects-by-property)
-[#12 Semicolons in Swift](https://github.com/Luur/SwiftTips#12-semicolons-in-swift)
-[#11 Fake AppDelegate](https://github.com/Luur/SwiftTips#11-fake-appdelegate)
-[#10 Invoke `didSet` when property’s value is set inside `init` context](https://github.com/Luur/SwiftTips#10-invoke-didset-when-propertys-value-is-set-inside-init-context)
-[#9 Change type of items in array](https://github.com/Luur/SwiftTips#9-change-type-of-items-in-array)
-[#8 `forEach` and `map` execution order difference](https://github.com/Luur/SwiftTips#8-foreach-and-map-execution-order-difference)
-[#7 Testing settings](https://github.com/Luur/SwiftTips#7-testing-settings)
-[#6 Tips for writing error messages](https://github.com/Luur/SwiftTips#6-tips-for-writing-error-messages)
-[#5 Profit to compiler](https://github.com/Luur/SwiftTips#5-profit-to-compiler)
-[#4 Combinations of pure functions](https://github.com/Luur/SwiftTips#4-combinations-of-pure-functions)
-[#3 Enumerated iteration](https://github.com/Luur/SwiftTips#3-enumerated-iteration)
-[#2 Easy way to hide Status Bar](https://github.com/Luur/SwiftTips#2-easy-way-to-hide-status-bar)
-[#1 Safe way to return element at specified index](https://github.com/Luur/SwiftTips#1-safe-way-to-return-element-at-specified-index)
+[#58 Load `UIView` from `Nib` file](#58-load-uiview-from-nib-file)
+[#57 Render HTML within a `UILabel`](#57-render-html-within-a-uilabel)
+[#56 Custom `Error` by adopting `LocalizedError` protocol](#56-custom-error-by-adopting-localizederror-protocol)
+[#55 'Result' type without value to provide](#55-result-type-without-value-to-provide)
+[#54 Given, When, Then](#54-given-when-then)
+[#53 `sut` and test lifecycle](#53-sut-and-test-lifecycle)
+[#52 Point on circle perimeter](#52-point-on-circle-perimeter)
+[#51 `zip()` function](#51-zip-function)
+[#50 StackView custom spacing](#50-stackview-custom-spacing)
+[#49 Named UIColor](#49-named-uicolor)
+[#48 `Result` error handling](#48-result-error-handling)
+[#47 Generics: Type parameters](#47-generics-type-parameters)
+[#46 Generics: Basics](#46-generics-basics)
+[#45 UserDefaults during testing](#45-userdefaults-during-testing)
+[#44 Additional Info to #38 Protocols: Optional methods](#44-additional-info-to-38-protocols-optional-methods)
+[#43 Responsible view controller for particular view](#43-responsible-view-controller-for-particular-view)
+[#42 Move between textfields](#42-move-between-textfields)
+[#41 Autogenerated `allCases` property for your `enum` (Swift 4.2)](#41-autogenerated-allcases-property-for-your-enum-swift-42)
+[#40 Protocols: Class-only](#40-protocols-class-only)
+[#39 Protocols: Inheritance and composition](#39-protocols-inheritance-and-composition)
+[#38 Protocols: Optional methods](#38-protocols-optional-methods)
+[#37 Protocols: Naming](#37-protocols-naming)
+[#36 Property observers, getter/setter and lazy are mutually exclusive](#36-property-observers-gettersetter-and-lazy-are-mutually-exclusive)
+[#35 Prepare Alamofire standalone functions to unit-testing](#35-prepare-alamofire-standalone-functions-to-unit-testing)
+[#34 Sort array of objects with multiple optional criteria](#34-sort-array-of-objects-with-multiple-optional-criteria)
+[#33 Remove object from array](#33-remove-object-from-array)
+[#32 Delegate naming](#32-delegate-naming)
+[#31 Run, Playground, run!](#31-run-playground-run)
+[#30 `DispatchGroup` usage](#30-dispatchgroup-usage)
+[#29 Remove duplicates](#29-remove-duplicates)
+[#28 Debugging: View Debugging](#28-debugging-view-debugging)
+[#27 Debugging: Breakpoints](#27-debugging-breakpoints)
+[#26 Debugging: Asserts](#26-debugging-asserts)
+[#25 Debugging: Log functions](#25-debugging-log-functions)
+[#24 Update `UIView` content with animation](#24-update-uiview-content-with-animation)
+[#23 Observe MOC changes](#23-observe-moc-changes)
+[#22 Split `String` into words](#22-split-string-into-words)
+[#21 Comparing tuples](#21-comparing-tuples)
+[#20 How to detect that user stop typing](#20-how-to-detect-that-user-stop-typing)
+[#19 Left/rigth text offset inside `UITextField`](#19-leftrigth-text-offset-inside-uitextfield)
+[#18 Common elements in two arrays](#18-common-elements-in-two-arrays)
+[#17 Apply gradient to Navigation Bar](#17-apply-gradient-to-navigation-bar)
+[#16 Get next element of array](#16-get-next-element-of-array)
+[#15 Split array by chunks of given size](#15-split-array-by-chunks-of-given-size)
+[#14 Transparent/Opaque Navigation Bar](#14-transparentopaque-navigation-bar)
+[#13 Group objects by property](#13-group-objects-by-property)
+[#12 Semicolons in Swift](#12-semicolons-in-swift)
+[#11 Fake AppDelegate](#11-fake-appdelegate)
+[#10 Invoke `didSet` when property’s value is set inside `init` context](#10-invoke-didset-when-propertys-value-is-set-inside-init-context)
+[#9 Change type of items in array](#9-change-type-of-items-in-array)
+[#8 `forEach` and `map` execution order difference](#8-foreach-and-map-execution-order-difference)
+[#7 Testing settings](#7-testing-settings)
+[#6 Tips for writing error messages](#6-tips-for-writing-error-messages)
+[#5 Profit to compiler](#5-profit-to-compiler)
+[#4 Combinations of pure functions](#4-combinations-of-pure-functions)
+[#3 Enumerated iteration](#3-enumerated-iteration)
+[#2 Easy way to hide Status Bar](#2-easy-way-to-hide-status-bar)
+[#1 Safe way to return element at specified index](#1-safe-way-to-return-element-at-specified-index)
+ +## [#58 Load `UIView` from `Nib` file]() + +You can load `UIView` from `Nib` file + +```swift +protocol NibLoadable { + static var nib:UINib { get } +} + +extension NibLoadable where Self: UIView { + static var nib: UINib { + let className = String(describing: self) + return UINib(nibName: className, bundle: Bundle(for: self)) + } + + static func view() -> Self? { + return nib.instantiate(withOwner: self, options: nil).first as? Self + } +} +``` + +Example: + +```swift +extension UIView:NibLoadable {} + +let inputBox = InputBoxView.view() +``` ## [#57 Render HTML within a `UILabel`]() @@ -88,7 +118,7 @@ extension String { Usage [example](https://github.com/Luur/SwiftTips/blob/master/Sources/57/example.playground/Contents.swift) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#56 Custom `Error` by adopting `LocalizedError` protocol]() @@ -150,7 +180,7 @@ extension ProfileError: LocalizedError { return NSLocalizedString("I don't know why", comment: "") } } - + public var recoverySuggestion: String? { switch self { case .invalidSettings: @@ -165,7 +195,7 @@ print(error.failureReason) print(error.recoverySuggestion) ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#55 `Result` type without value to provide]() @@ -210,7 +240,7 @@ func login(with credentials: Credentials, handler: @escaping (_ result: Result CGPoint { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#51 `zip()` function](https://twitter.com/szubyak/status/1032565476143050753) @@ -294,7 +324,7 @@ Note: I would recomend to wrap the output from `zip()` into array to make its ou One of the useful features of `zip()` is that if your two arrays arent equal in size it will choose the shorter one. Yes, it will not crash your application, just ignore element which doesn’t have a match in second sequence. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#50 `StackView` custom spacing](https://twitter.com/szubyak/status/1031853568586854400) @@ -313,7 +343,7 @@ Also, in iOS 11 Apple introduced default and system spacing properties on the `U stackview.setCustomSpacing(UIStackView.spacingUseSystem, after: label) ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#49 Named UIColor](https://twitter.com/szubyak/status/1031489173440684032) @@ -329,7 +359,7 @@ view.backgroundColor = UIColor(named: "FerrariRed") Inside storyboards you can use created named color by selecting it from the color dropdown menu. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#48 `Result` error handling]() @@ -366,7 +396,7 @@ class TasksStore: TasksStoreProtocol { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#47 Generics: Type parameters]() @@ -376,7 +406,7 @@ You can provide more than one type parameter by writing multiple names within th In most cases, type parameters have descriptive names, such as `Key` and `Value` in `Dictionary` and `Element` in `Array`, which tells about the relationship between the type parameter and the generic type or function it’s used in. However, when there isn’t a meaningful relationship between them, it’s traditional to name them using single letters such as `T`, `U`, and `V`. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#46 Generics: Basics]() @@ -402,7 +432,7 @@ func swapTwoValues(_ a: inout T, _ b: inout T) { ``` The body of our two functions is the same. But the first line of is slightly different. The generic version of the function uses a placeholder type name (called `T`) instead of an actual type name (such as `Int`, `String`, or `Double`). The placeholder type name doesn’t say anything about what `T` must be, but it does say that both `a` and `b` must be of the same type `T`. The actual type to use in place of `T` is determined each time the function is called. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#45 UserDefaults during testing]() @@ -440,7 +470,7 @@ class MyTests: XCTestCase { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#44 Additional Info to #38 Protocols: Optional methods]() @@ -459,7 +489,7 @@ extension CarEngineStatusDelegate { This way the class/struct that will use our protocol will only need to implement `func engineDidStop()`. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#43 Responsible view controller for particular view](https://twitter.com/szubyak/status/1015960175247872000) @@ -481,7 +511,7 @@ extension UIView { You should only use it when you really need it – if you’re able to call methods directly using a delegate or indirectly by posting notifications then do it in first place. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#42 Move between textfields](https://twitter.com/szubyak/status/1011979216802533376) @@ -501,7 +531,7 @@ func textFieldShouldReturn(_ textField: UITextField) -> Bool { If you need to force the first responder to resign itself and aren’t sure which textfield is in control, it’s easier to use `view.endEditing(true)`. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#41 Autogenerated `allCases` property for your `enum` (Swift 4.2)](https://twitter.com/szubyak/status/1008631549888167937) @@ -531,7 +561,7 @@ for car in Cars.allCases { print(car) } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#40 Protocols: Class-only](https://twitter.com/szubyak/status/1006181062827966465)
@@ -542,7 +572,7 @@ weak var delegate: CarDelegate? ``` The `weak` keyword can't be used with structs and enums, because they are value types. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#39 Protocols: Inheritance and composition](https://twitter.com/szubyak/status/1005056393697742849)
@@ -560,7 +590,7 @@ protocol CarMovingStatusDelegate { } protocol CarDelegate: CarMovingStatusDelegate, CarEngineStatusDelegate { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#38 Protocols: Optional methods](https://twitter.com/szubyak/status/1004694921457086464)
@@ -612,7 +642,7 @@ delegate?.engineWillStop?() The `delegate` property is optional because there might not be a delegate assigned. And in the `CarDelegate` protocol we made `engineWillStop()` an optional requirement, so even if a delegate is present it might not implement that method. As a result, we need to use optional chaining. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#37 Protocols: Naming](https://twitter.com/szubyak/status/1003204523006021632)
@@ -622,7 +652,7 @@ If we are talking about naming the protocol itself: Briefly talking about methods names inside protocol, you can use whatever names you want. But, if your protocol is created to represent delegates please look: [#32 Delegate naming](https://github.com/Luur/SwiftTips#32-delegate-naming) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#36 Property observers, getter/setter and lazy are mutually exclusive](https://twitter.com/szubyak/status/1001754575857168384)
@@ -630,7 +660,7 @@ Little thing that surprisingly became a discovery for me, because it's rare case ![](../master/Sources/36/img.png) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#35 Prepare Alamofire standalone functions to unit-testing]() @@ -713,7 +743,7 @@ class AlamofireWrapperSpy: AlamofireWrapper { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#34 Sort array of objects with multiple optional criteria](https://twitter.com/szubyak/status/999579540602216448) @@ -746,7 +776,7 @@ let places = [Place(rating: 3, distance: 127), Place(rating: 4, distance: 423), let sortedPlaces = sortPlacesByRatingAndDistance(places) // [{rating 5, nil}, {rating 4, distance 423}, {rating 3, distance 127}, {nil, distance 34}, {nil, distance 100}, {nil, nil}] ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#33 Remove object from array](https://twitter.com/szubyak/status/997471185008021505) @@ -762,12 +792,12 @@ extension Array where Element: Equatable { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#32 Delegate naming](https://twitter.com/szubyak/status/997063113659813890) When creating custom delegate methods take into consideration the following list items: -* You can give the name to your delegate property `delegate`, if it is just one of them, or put `delegate` at the end, when it is more than one. Here is the example, `WKWebView` has `uiDelegate` and `navigationDelegate` properties that can point to two different objects. 
 +* You can give the name to your delegate property `delegate`, if it is just one of them, or put `delegate` at the end, when it is more than one. Here is the example, `WKWebView` has `uiDelegate` and `navigationDelegate` properties that can point to two different objects.
 * You should use Apple’s standard approach to avoid verb conjugation. It says that many of your method names will use `will`, `did`, and `should`. * Start the name by identifying the class of the object that’s sending the message `func tableView(_ tableView: UITableView,...`. It helps in situations where there is more than one object that can send a message . @@ -776,7 +806,7 @@ As a result, Apple delegates have a very specific naming convention: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#31 Run, Playground, run!]() @@ -788,7 +818,7 @@ Tell the playground it should continue running forever, otherwise it will termin PlaygroundPage.current.needsIndefiniteExecution = true ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#30 `DispatchGroup` usage]() @@ -819,7 +849,7 @@ Each call to `enter()` must be matched later on with a call to `leave()`, after * A further option is `wait(timeout:)`. This blocks the current thread, but after the timeout specified, continues anyway. To create a timeout object of type `DispatchTime`, the syntax `.now() + 1` will create a timeout one second from now. * `wait(timeout:)` returns an enum that can be used to determine whether the group completed, or timed out. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#29 Remove duplicates](https://twitter.com/szubyak/status/993399930457939968) @@ -841,7 +871,7 @@ extension Array { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#28 Debugging: View Debugging](https://twitter.com/szubyak/status/992667725574045696) @@ -858,7 +888,7 @@ If you have a complicated view layout, `View Debugging` > `Show View Frames` opt More about view debugging [here](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/special_debugging_workflows.html) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#27 Debugging: Breakpoints](https://twitter.com/szubyak/status/989442320260108288) @@ -883,7 +913,7 @@ In Xcode debug console you can use `po` to print what you need during pause. ![](../master/Sources/27/img3.png) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#26 Debugging: Asserts](https://twitter.com/szubyak/status/989153864472547328) @@ -916,7 +946,7 @@ fatalError("ERROR") More about asserts and optimisation levels you can find [here](https://agostini.tech/2017/10/01/assert-precondition-and-fatal-error-in-swift/) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#25 Debugging: Log functions](https://twitter.com/szubyak/status/988328809681342464) @@ -942,7 +972,7 @@ It’s `\n` by default, which means "line break". print("one", "two", "three", "four", terminator: " five") //one two three four five ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#24 Update `UIView` content with animation](https://twitter.com/szubyak/status/985434399138304000) @@ -966,7 +996,7 @@ label.fadeTransition(1) label.text = "Updated test content with animation" ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#23 Observe MOC changes](https://twitter.com/szubyak/status/983647253234626560) @@ -999,7 +1029,7 @@ func changeNotification(_ notification: Notification) { NotificationCenter.default.addObserver(self, selector: #selector(self.changeNotification(_:)), name: .NSManagedObjectContextObjectsDidChange, object: moc) ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#22 Split `String` into words](https://twitter.com/szubyak/status/981833649296498689) @@ -1015,7 +1045,7 @@ extension String { } } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#21 Comparing tuples](https://twitter.com/szubyak/status/980119909387599873) @@ -1032,7 +1062,7 @@ if car == company { ``` Printed result will be: `Equal` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#20 How to detect that user stop typing](https://twitter.com/szubyak/status/978659051893555201) @@ -1067,7 +1097,7 @@ extension TestViewController: UITextFieldDelegate { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#19 Left/rigth text offset inside `UITextField`](https://twitter.com/szubyak/status/976547738908323840) @@ -1101,7 +1131,7 @@ extension UITextField { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#18 Common elements in two arrays](https://twitter.com/szubyak/status/975736596661178369) @@ -1114,7 +1144,7 @@ func &(lhs: [T], rhs: [T]) -> [T] { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#17 Apply gradient to Navigation Bar](https://twitter.com/szubyak/status/974580828750704641) @@ -1151,7 +1181,7 @@ extension UINavigationBar { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#16 Get next element of array](https://twitter.com/szubyak/status/973146709030207489) @@ -1168,7 +1198,7 @@ extension Array where Element: Hashable { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#15 Split array by chunks of given size](https://twitter.com/szubyak/status/971351860820037632) @@ -1185,7 +1215,7 @@ extension Array { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#14 Transparent/Opaque Navigation Bar](https://twitter.com/szubyak/status/970962096245628929) Scene with `UIImageView` on top looks stylish if navigation bar is transparent. @@ -1203,7 +1233,7 @@ func opaqueNavigationBar() { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#13 Group objects by property](https://twitter.com/szubyak/status/966248375988490240) @@ -1259,7 +1289,7 @@ Result: Also in-box [alternative](https://developer.apple.com/documentation/swift/dictionary/2919592-init) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#12 Semicolons in Swift](https://twitter.com/szubyak/status/963144748004454400) @@ -1271,7 +1301,7 @@ func sum(a: Int, b: Int) -> Int { } ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#11 Fake AppDelegate](https://twitter.com/szubyak/status/963013740265385984) @@ -1279,7 +1309,7 @@ Unit testing shouldn’t have any side effects. While running tests, Xcode first You can find `main.swift` file [here](../master/Sources/11/main.swift) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#10 Invoke `didSet` when property’s value is set inside `init` context](https://twitter.com/szubyak/status/961707655105531905) @@ -1323,7 +1353,7 @@ Result: Function: propertyBB ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#9 Change type of items in array](https://twitter.com/szubyak/status/956544356370059265) @@ -1335,13 +1365,13 @@ let mapNumbers = numbers.map { Int($0) } // [Optional(1), Optional(2), Optional let compactNumbers = numbers.compactMap { Int($0) } // [1, 2, 3, 4] ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#8 `forEach` and `map` execution order difference](https://twitter.com/szubyak/status/956538549444186112) Execution order is interesting difference between `forEach` and `map`: `forEach` is guaranteed to go through array elements in its sequence, while `map` is free to go in any order. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#7 Testing settings](https://twitter.com/szubyak/status/955468985121886208) @@ -1350,7 +1380,7 @@ Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) ![](../master/Sources/7/img.jpeg) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#6 Tips for writing error messages](https://twitter.com/szubyak/status/955054366419013632) @@ -1360,13 +1390,13 @@ Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) [Common​ ​Types​ ​of​ ​Error​ ​Messages](../master/Sources/6/Common​​Error​​Messages.pdf) -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#5 Profit to compiler](https://twitter.com/szubyak/status/954329152160780288) Do you know that using `map` gives profit to the compiler: it's now clear we want to apply some code to every item in an array, then like in `for` loop we could have `break` on halfway through. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#4 Combinations of pure functions](https://twitter.com/szubyak/status/953993641391017984) @@ -1384,7 +1414,7 @@ let max = colors.max() // white let last = colors.sorted().last // white ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#3 Enumerated iteration](https://twitter.com/szubyak/status/951039299759362048) @@ -1406,7 +1436,7 @@ Result: Also be careful with this tricky thing, `enumerated` on collection will not provide actual indices, but monotonically increasing integer, which happens to be the same as the index for Array but not for anything else, especially slices. -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#2 Easy way to hide Status Bar](https://twitter.com/szubyak/status/950687583222337537) @@ -1427,7 +1457,7 @@ let testVC = TestViewController() print("statusBarHidded \(testVC.prefersStatusBarHidden)") // true ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents) ## [#1 Safe way to return element at specified index](https://twitter.com/szubyak/status/950345927054778368) @@ -1445,4 +1475,4 @@ let selectedCar1 = cars[safe: 3] // Toyota let selectedCar2 = cars[safe: 6] // not crash, but nil ``` -Back to [Top](https://github.com/Luur/SwiftTips#-table-of-contents) +Back to [Top](#-table-of-contents)