From 48b8f7287ed38046f13e8bf86be86685b7c815cf Mon Sep 17 00:00:00 2001 From: Michael Henry Pantaleon Date: Sat, 29 Dec 2018 00:13:02 +0900 Subject: [PATCH 1/2] loading uiview from nib file. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index aa036ef..f8dac8b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Here's list of Swift tips & tricks with all additional sources (playgrounds, ima ## 📃 Table of contents +[#58 Load `UIView` from `Nib` file](#58-load-uiview-from-nib-file)
[#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)
@@ -66,6 +67,35 @@ Here's list of Swift tips & tricks with all additional sources (playgrounds, ima [#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]() + +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`]() You can render HTML strings within a `UILabel` using a special initializer of `NSAttributedString` and passing in `NSAttributedString.DocumentType.html` for `.documentType`. But in most cases it is not enough to display it as is. If we want to add custom font or color we need to use CSS (add CSS header to our HTML string). From c94b9822b5e293c3ee240f923f5ab91a397115f4 Mon Sep 17 00:00:00 2001 From: Michael Henry Pantaleon Date: Sat, 29 Dec 2018 00:33:26 +0900 Subject: [PATCH 2/2] make links to be relative. --- README.md | 232 +++++++++++++++++++++++++++--------------------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index f8dac8b..0a9a1d9 100644 --- a/README.md +++ b/README.md @@ -9,63 +9,63 @@ Here's list of Swift tips & tricks with all additional sources (playgrounds, ima ## 📃 Table of contents [#58 Load `UIView` from `Nib` file](#58-load-uiview-from-nib-file)
-[#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)
+[#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]() @@ -118,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]() @@ -180,7 +180,7 @@ extension ProfileError: LocalizedError { return NSLocalizedString("I don't know why", comment: "") } } - + public var recoverySuggestion: String? { switch self { case .invalidSettings: @@ -195,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]() @@ -240,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) @@ -324,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) @@ -343,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) @@ -359,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]() @@ -396,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]() @@ -406,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]() @@ -432,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]() @@ -470,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]() @@ -489,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) @@ -511,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) @@ -531,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) @@ -561,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)
@@ -572,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)
@@ -590,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)
@@ -642,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)
@@ -652,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)
@@ -660,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]() @@ -743,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) @@ -776,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) @@ -792,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 . @@ -806,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!]() @@ -818,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]() @@ -849,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) @@ -871,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) @@ -888,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) @@ -913,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) @@ -946,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) @@ -972,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) @@ -996,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) @@ -1029,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) @@ -1045,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) @@ -1062,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) @@ -1097,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) @@ -1131,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) @@ -1144,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) @@ -1181,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) @@ -1198,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) @@ -1215,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. @@ -1233,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) @@ -1289,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) @@ -1301,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) @@ -1309,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) @@ -1353,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) @@ -1365,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) @@ -1380,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) @@ -1390,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) @@ -1414,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) @@ -1436,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) @@ -1457,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) @@ -1475,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)