You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+15-11Lines changed: 15 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -226,7 +226,7 @@ let cell = tableView.dequeueReusableCell(for: indexPath) as MyCustomCell
226
226
let cell: MyCustomCell = tableView.dequeueReusableCell(for: indexPath)
227
227
```
228
228
229
-
As long as **Swift can use type-inference to understand that you'll want a cell of type `MyCustomCell`** (either using `as MyCystomCell` or explicitly typing the receiving variable `cell: MyCustomCell`), it will magically infer both the cell class to use and thus its `reuseIdentifier` needed to dequeue the cell, and which exact type to return to save you a type-cast.
229
+
As long as **Swift can use type-inference to understand that you'll want a cell of type `MyCustomCell`** (either using `as MyCustomCell` or explicitly typing the receiving variable `cell: MyCustomCell`), it will magically infer both the cell class to use and thus its `reuseIdentifier` needed to dequeue the cell, and which exact type to return to save you a type-cast.
230
230
231
231
* No need for you to manipulate `reuseIdentifiers` Strings manually anymore!
232
232
* No need to force-cast the returned `UITableViewCell` instance down to your `MyCustomCell` class either!
Now all you have is **a beautiful code and type-safe cells**, with compile-type checking, and no more String-based API!
257
257
258
-
> 💡 If the cell class is computed at runtime in a variable, you won't be able to use `as theVariable` or `let cell: theVariable` obviously… but instead you can use the optional parameter `cellType` (which otherwise gets infered by the return type and is thus not necessary to provide explicitly)
258
+
> 💡 If the cell class you want to dequeue is computed at runtime and stored in a variable, you won't be able to use `as theVariable` or `let cell: theVariable` obviously. Instead, you can use the optional parameter `cellType` (which otherwise gets infered by the return type and is thus not necessary to provide explicitly)
259
259
>
260
260
> <details>
261
261
> <summary>📑 Example with a cell type determined at runtime</summary>
@@ -266,15 +266,17 @@ Now all you have is **a beautiful code and type-safe cells**, with compile-type
>// Then fill the content of your cell (using methods/properties from `ParentCell` type)
278
280
>return cell
279
281
> }
280
282
> ```
@@ -286,7 +288,7 @@ Now all you have is **a beautiful code and type-safe cells**, with compile-type
286
288
287
289
# Type-safe XIB-based reusable views
288
290
289
-
`Reusable` also allows you to create reusable custom views designed in Interface Builder to reuse them in other XIBs or by code, like creating custom UI widgets used in multiple places in your app.
291
+
`Reusable` also allows you to create reusable custom views designed in Interface Builder to reuse them in other XIBs or Storyboards, or by code. This allows you to treat those views like custom UI widgets that can be used in multiple places in your app.
290
292
291
293
## 1. Declare your views to conform to `NibLoadable` or `NibOwnerLoadable`
292
294
@@ -304,7 +306,7 @@ final class NibBasedFileOwnerView: UIView, NibOwnerLoadable { /* and that's it!
304
306
```
305
307
306
308
> 💡 You should use the second approach if you plan to use your custom view in another XIB or Storyboard.
307
-
> This will allow you to just drop a UIView in a XIB/Storyboard and change its class to the class of your custom XIB-based view to use it. That custom view will then automagically load its own content from the associated XIB when instantiated by the storyboard containing it, without having to write additional code to load the content of the custom view manually every time.
309
+
> This will allow you to just drop a UIView in a XIB/Storyboard and change its class in IB's inspector to the class of your custom XIB-based view to use it. That custom view will then automagically load its own content from the associated XIB when instantiated by the storyboard containing it, without having to write additional code to load the content of the custom view manually every time.
308
310
309
311
## 2. Design your view in Interface Builder
310
312
@@ -339,21 +341,21 @@ final class MyCustomWidget: UIView, NibOwnerLoadable {
339
341
```
340
342
</details>
341
343
342
-
Then that widget can be integrated in a Storyboard Scene (or any other XIB) by simply dropping a `UIView` on the Storyboard, and changing its class to `MyCustomWidget`.
344
+
Then that widget can be integrated in a Storyboard Scene (or any other XIB) by simply dropping a `UIView` on the Storyboard, and changing its class to `MyCustomWidget` in IB's inspector.
343
345
344
346
<details>
345
347
<summary>🖼 Example of a `NibOwnerLoadable` custom view once integrated in another Storyboard</summary>
346
348
347
349
* In the capture below, all blue square views have a custom class of `MyCustomWidget` set in Interface Builder.
348
-
* When selecting one of this custom class, you have direct access to all `@IBOutlet` that this `MyCustomWidget` exposes, which allows you to connect them to other views of the Storyboard if needed
349
-
* When selecting one of this custom class, you also have access to all the `@IBInspectable` properties. For example, in the capture below, you can see the "Rect color" and "Text" inspectable properties on the right panel, that you can change right from the Storyboard integrating your custom widget.
350
+
* When selecting one of these custom views, you have direct access to all `@IBOutlet` that this `MyCustomWidget` exposes, which allows you to connect them to other views of the Storyboard if needed
351
+
* When selecting one of these custom views, you also have access to all the `@IBInspectable` properties. For example, in the capture below, you can see the "Rect color" and "Text" inspectable properties on the right panel, that you can change right from the Storyboard integrating your custom widget.
350
352
351
353

352
354
</details>
353
355
354
356
## 3a. Auto-loading the content of a `NibOwnerLoadable` view
355
357
356
-
If you used `NibOwnerLoadable` and made your custom view the File's Owner of your XIB, you should then override `init?(coder:)` so that it load it's associated XIB as subviews and add constraints automatically:
358
+
If you used `NibOwnerLoadable` and made your custom view the File's Owner of your XIB, you should then override `init?(coder:)` so that it loads it's associated XIB as subviews and add constraints automatically:
@@ -365,9 +367,11 @@ final class MyCustomWidget: UIView, NibOwnerLoadable {
365
367
}
366
368
```
367
369
368
-
Overriding `init?(coder:)`allows your `MyCustomWidget` custom view to load its content from the associated XIB `MyCustomWidget.xib` and add it as subviews of itself.
370
+
`self.loadNibContent()`is a method provided by the `NibOwnerLoadable` mixin. It basically loads the content from the associated `MyCustomWidget.xib`, then add all the root views in that XIB as subviews of your `MyCustomWidget`, with appropriate layout constraints to make them the same size as your `MyCustomWidget` container view.
369
371
370
-
_💡 Note: it is also possible to override `init(frame:)`, in order to be able to create an instance of that view programatically and call `loadNibContent()` to fill with views if needed._
372
+
Overriding `init?(coder:)` and calling `self.loadNibContent()` thus allows you to have that content automatically loaded by the system when that `MyCustomWidget` in included in another XIB or in a Storyboard (as `init?(coder:)` is the `init` that is called by iOS to create those instances in a XIB or Storyboard)
373
+
374
+
_💡 Note: it is also possible to override `init(frame:)` similarly, in order to be able to also create an instance of that view manually via code if needed._
0 commit comments