Slide 1

Slide 1 text

7$/$ ӣթഅ 9DPEF1SFWJFXT ఋ׮о*#ܳߡܽ੉ਬ

Slide 2

Slide 2 text

7$/$ ӣթഅ 9DPEF1SFWJFXT ఋ׮о*#ܳߡܽ੉ਬ*#হ੉ѐߊೞӝ

Slide 3

Slide 3 text

Xcode Previews Xcode Previews in UIKit Problems with Storyboard, XIB UI programming using Xcode Previews $POUFOUT

Slide 4

Slide 4 text

Xcode Previews

Slide 5

Slide 5 text

• Xcode 11 • MacOS Catalina 9DPEF1SFWJFXT

Slide 6

Slide 6 text

#BDLHSPVOE ` Mastering Xcode Previews @WWDC 2019

Slide 7

Slide 7 text

#BDLHSPVOE Mastering Xcode Previews @WWDC 2019

Slide 8

Slide 8 text

#BDLHSPVOE Mastering Xcode Previews @WWDC 2019

Slide 9

Slide 9 text

• Configuring • Building • Running • Navigating • Getting to the state #BDLHSPVOE

Slide 10

Slide 10 text

#BDLHSPVOE Mastering Xcode Previews @WWDC 2019

Slide 11

Slide 11 text

#BDLHSPVOE Mastering Xcode Previews @WWDC 2019

Slide 12

Slide 12 text

#BDLHSPVOE Mastering Xcode Previews @WWDC 2019

Slide 13

Slide 13 text

Time consuming

Slide 14

Slide 14 text

9DPEF1SFWJFXT Mastering Xcode Previews @WWDC 2019

Slide 15

Slide 15 text

struct PriceView_Preview: PreviewProvider { static var previews: some View { PriceView(price:…) .previewLayout(.sizeThatFits) .environment(\.colorScheme, .dark) } }

Slide 16

Slide 16 text

4BNQMF

Slide 17

Slide 17 text

Demo

Slide 18

Slide 18 text

Previews ز੘ ਗܻ

Slide 19

Slide 19 text

• 2 Main Components • A preview build • Xcode extension ( live view ) 9DPEF1SFWJFXT

Slide 20

Slide 20 text

• Normal Build • Xcode scheme, build settings ਸ ٮܰח ੌ߈੸ੋ ࠽٘ • Preview Build • ୶о compile optionҗ ೣԋ normal buildܳ ഛ੢ೠ ߹ب੄ ࠽٘ 9DPEF1SFWJFXT

Slide 21

Slide 21 text

• Xcode build artifact ী normal ࠽٘৬ ೣԋ ઓ੤ • Object file, artifact ҕਬ • Additional Options • Interactive UI ࣻ੿ / dynamic behavior ೲਊ • ਗࠄ ౵ੌ ৻ ୶о੸ੋ ࣗझ ౵ੌ ࢤࢿ • ਗࠄ ࣗझ ௏٘ܳ ࠗ࠙੸ਵ۽ UIܳ ࣻ੿ೡ ࣻ ੓ח ௏٘۽ ߸҃ by method swizzling 1SFWJFX#VJME

Slide 22

Slide 22 text

1SFWJFX#VJME

Slide 23

Slide 23 text

struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

Slide 24

Slide 24 text

@_private(sourceFile: "ContentView.swift") import LetSwiftPreview import SwiftUI import SwiftUI extension ContentView_Previews { @_dynamicReplacement(for: previews) private static var __preview__previews: some View { #sourceLocation(file: "/Users/nate/Documents/samples/SwiftUI/ LetSwiftPreview/LetSwiftPreview/LetSwiftPreview/ContentView.swift", line: 19) AnyView(__designTimeSelection(ContentView(), "#40077.[2].[0].property.[0]. [0]")) #sourceLocation() } } typealias ContentView = LetSwiftPreview.ContentView typealias ContentView_Previews = LetSwiftPreview.ContentView_Previews

Slide 25

Slide 25 text

• Xcodeо пࢤࢿػ ౵ੌਸ ة݀੸ੋ dynamic library۽ ࠽٘ • library -> Preview applicationਵ۽ ۽٘ 9DPEF1SFWJFXT

Slide 26

Slide 26 text

Xcode Previews in UIKit

Slide 27

Slide 27 text

• UIViewController ب Previews ࢎਊ оמ • UIViewControllerRepresentable protocol 9DPEF1SFWJFXTJO6*,JU func makeUIViewController(context: Self.Context) -> Self.UIViewControllerType func updateUIViewController( _ uiViewController: Self.UIViewControllerType, context: Self.Context )

Slide 28

Slide 28 text

• UIView ب Previews ࢎਊ оמ • UIViewRepresentable protocol 9DPEF1SFWJFXTJO6*,JU func makeUIView(context: Self.Context) -> Self.UIViewType func updateUIView( _ uiView: Self.UIViewType, context: Self.Context )

Slide 29

Slide 29 text

• Previews ীࢲ ࢎਊೞӝ ਤೠ protocol • UIKit -> SwiftUI • SwiftUI ܳ ࢎਊೡ ࣻ ੓ח ജ҃ীࢲ݅ ੉ਊ оמ 6*7JFX3FQSFTFOUBCMF

Slide 30

Slide 30 text

• Debug ࠽٘ ࢸ੿ ߸҃ • iOS Deployment target : iOS13 • canImport, @available 9DPEF1SFWJFXTJ04

Slide 31

Slide 31 text

#if canImport(SwiftUI) && DEBUG import SwiftUI @available(iOS 13.0, *) struct PriceView_Preview: UIViewRepresentable, PreviewProvider { let price: Price func makeUIView(context: Self.Context) -> PriceView { PriceView().also { $0.price = price } } func updateUIView(_ view: PriceView, context: Self.Context) { … } static var previews: some View { PriceView_Preview(price: …) } } #endif

Slide 32

Slide 32 text

Demo

Slide 33

Slide 33 text

Problems with Storyboard, XIB

Slide 34

Slide 34 text

• XML • ੍Ѣա ࣻ੿ೡ ࣻ হח XML • ࣻ ߔ઴ ੉࢚੄ ௾ ౵ੌ 3FBEBCJMJUZ

Slide 35

Slide 35 text

3FBEBCJMJUZ

Slide 36

Slide 36 text

• XML • ੍Ѣա ࣻ੿ೡ ࣻ হח XML • ࣻ ߔ઴ ੉࢚੄ ௾ ౵ੌ • э਷ Viewܳ ࣻ੿ೞݶ? • PR 3FBEBCJMJUZ

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

• ౵ੌ੉ ੼੼ ழ૗ • যו࢜ ࣻभ ѐ੄ झ௼ܽ੉ ೞա੄ ౵ੌী.. • Source control ߄Ե ٸ݃׮ 4UPSZCPBSET

Slide 39

Slide 39 text

• IBח Swift ௏٘ܳ ੜ ݽܴ(vice versa) • IBOutlet, IBAction ਸ ా೧ োѾ • IBীࢲ Viewܳ ૑ਕب ௏٘ח Ӓ؀۽… • Cell in TableView ীࢲ identifier۽ оઉয়ӝ (Typecast ೙ࣻ ) 4XJGU*OUFSGBDFCVJMEFS

Slide 40

Slide 40 text

• Color asset ਵ۽ ࢸ੿ೠ ࢝੉ viewDidLoad, viewWillAppear, awakeFromNib ࣻ੿ ࠛо • Callstack • viewDidLoad(viewWillAppear) -> traitCollectionDidChanged ->
 ੿੄ػ asset color۽ trait collection ੸ਊ *OUFSGBDFCVJMEFSCVHT

Slide 41

Slide 41 text

UI programming using Xcode Previews

Slide 42

Slide 42 text

• Visualization • Image > Text • Views, Constraints ҳઑ ౵ঈ 1SPHSBNNBUJDBMMZ6*

Slide 43

Slide 43 text

• Verbose • Complex • Difficult to read 1SPHSBNNBUJDBMMZ6*

Slide 44

Slide 44 text

header.translatesAutoresizingMaskIntoConstraints = false let cn1 = NSLayoutConstraint(item: header, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 20) let cn2 = NSLayoutConstraint(item: header, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1.0, constant: -20) let cn3 = NSLayoutConstraint(item: header, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 60) let cn4 = NSLayoutConstraint(item: header, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 20) view.addConstraints([cn1, cn2, cn3, cn4])

Slide 45

Slide 45 text

• Layout libraries • PureLayout, Cartogrphy, Snapkit … 1SPHSBNNBUJDBMMZ6*

Slide 46

Slide 46 text

header.snp.makeConstraints { maker in maker.leading.trailing.top.equalToSuperview().inset(20) maker.height.equalTo(60) }

Slide 47

Slide 47 text

• ૒ҙ੸ਵ۽ ചݶਸ ੉೧ೞӝ য۰਑ 1SPHSBNNBUJDBMMZ6*

Slide 48

Slide 48 text

blackView.snp.makeConstraints { make in make.center.equalTo(view) make.size.equalTo(CGSize(width: 100, height: 100)) } redView.snp.makeConstraints { make in make.top.equalTo(blackView.snp.bottom).offset(20.0) make.right.equalTo(blackView.snp.left).offset(-20.0) make.size.equalTo(CGSize(width: 100, height: 100)) } yellowView.snp.makeConstraints { make in make.top.equalTo(blackView.snp.bottom).offset(20.0) make.left.equalTo(blackView.snp.right).offset(20.0) make.size.equalTo(CGSize(width: 100, height: 100)) } blueView.snp.makeConstraints { make in make.bottom.equalTo(blackView.snp.top).offset(-20.0) make.left.equalTo(blackView.snp.right).offset(20.0) make.size.equalTo(CGSize(width: 100, height: 100)) } greenView.snp.makeConstraints { make in make.bottom.equalTo(blackView.snp.top).offset(-20.0) make.right.equalTo(blackView.snp.left).offset(-20.0) make.size.equalTo(CGSize(width: 100, height: 100))

Slide 49

Slide 49 text

• ૒ҙ੸ਵ۽ ചݶਸ ੉೧ೞӝ য۰਑ • View ҳઑܳ ౵ঈೞӝ ਤ೧ ੹୓ ௏٘ ౵ঈ ೙ਃ • View Hierarchy ↑ ➡ Time ↑ • Layout library੄ ೠ҅ 1SPHSBNNBUJDBMMZ6*

Slide 50

Slide 50 text

• makeConstraints: э਷ ࠗݽܳ ыח Views݅ оמ • addSubview / makeConstraints ௏٘ ܻ࠙ • Nested ҳઑੌ ٸ children ਸ ݢ੷ ੘ࢿ 4OBQ,JU

Slide 51

Slide 51 text

IBKit https://github.com/glwithu06/IBKit

Slide 52

Slide 52 text

• Visualization • ૒ҙ੸ੋ ௏٘ ੉೧ *#,JU

Slide 53

Slide 53 text

• Visualization -> Xcode Previews • ૒ҙ੸ੋ ௏٘ ੉೧ -> Declarative झఋੌ *#,JU

Slide 54

Slide 54 text

UIView() { UIView().identifier(“upper") .backgroundColor(.cyan) .makeConstraints { $0.top.left.right.equalToSuperview() $0.height.equalTo(30) } UIView().identifier("lower") .backgroundColor(.blue) .makeConstraints { $0.top.equalTo($0.views.upper.bottom) $0.bottom.left.right.equalToSuperview() $0.height.equalTo(30) } } .identifier(“yellow") .assign(to: \.container, on: self)

Slide 55

Slide 55 text

Demo

Slide 56

Slide 56 text

• UIViewRepresentable • UIViewControllerRepresentable • Preview(root:) 9DPEF1SFWJFXT

Slide 57

Slide 57 text

Preview sample

Slide 58

Slide 58 text

• @_functionBuilder • Swift5.1 private feature %FDMBSBUJWFTUZMF

Slide 59

Slide 59 text

@_functionBuilder struct ViewBulder { static func buildBlock() -> Builder { BuilderImpl(children: []) } static func buildEither(first: UIView) -> Builder { BuilderImpl(children: [first]) } static func buildEither(second: UIView) -> Builder { BuilderImpl(children: [second]) } static func buildIf(_ view: UIView?) -> Builder { BuilderImpl(children: view.map { [$0] } ?? []) } static func buildBlock(_ views: UIView...) -> Builder { BuilderImpl(children: views) } … }

Slide 60

Slide 60 text

• SnapKit ӝ߈ Layout
 • addSubview -> SnapKit.makeConstraints • Dynamic member lookup -BZPVU func makeConstraints(_ closure: @escaping (ConstraintMaker) -> Void) -> Self

Slide 61

Slide 61 text

.makeConstraints { $0.left.right.equalToSuperview().inset(50) $0.top.equalTo($0.views.description.bottom).offset(30) $0.height.equalTo(30).priority(ConstraintPriority.low) }

Slide 62

Slide 62 text

• KeyPath Binding "TTJHOWJFXT func assign( to keyPath: ReferenceWritableKeyPath, on object: Root ) -> Self

Slide 63

Slide 63 text

Wrap up

Slide 64

Slide 64 text

• PreviewProvider protocol • Group / ForEach • previewLayout / previewDevice / environment • Development Assets • Pinning 9DPEF1SFWJFXT

Slide 65

Slide 65 text

• Preview Build • Derived source code • Preview library 9DPEF1SFWJFXT

Slide 66

Slide 66 text

• UIViewControllerRepresentable • UIViewRepresentable • makeUIView / updateUIView • canImport(SwiftUI) 9DPEF1SFWJFXTJO6*,JU

Slide 67

Slide 67 text

• Readability • Maintenance (Storyboard) • Swift <-> Interface Builder • Interface Builder bugs 4UPSZ#PBSE 9*#

Slide 68

Slide 68 text

• Visualization • Intuitive • IBKit 1SPHSBNNBUJDBMMZ6*

Slide 69

Slide 69 text

8FsSFIJSJOH

Slide 70

Slide 70 text

No content