SlideShare uma empresa Scribd logo
1 de 155
Baixar para ler offline
SwiftUI for Production
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
🥰 Like SwiftUI?
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
🛠 Used SwiftUI?
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
🥳
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
🥰
+
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI
🤔🤩😑
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
Where the compiler thinks the problem is.
Where the problem actually is.
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
List {
ForEach(contents, id: .id) { partialContent in
NavigationLink(destination: ContentListingView() {
CardView(model: CardViewModel.transform(partialContent))
.listRowBackground(self.bgColor)
.background(self.bgColor)
}
.listRowBackground(self.bgColor)
.background(self.bgColor)
}
.listRowBackground(self.bgColor)
.background(self.bgColor) ???
How to !@#$ change the BG color
of a table view?!
private func filtersView() -> some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: .filterSpacing) {
ForEach(filters.appliedFilters, id: .self) { filter in
AppliedFilterView(filter: filter, type: .default) {
self.contentsMC.updateFilters(newFilters: self.filters)
}
}
}
}
.padding([.top], .filtersPaddingTop)
}
private func filtersView() -> some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: .filterSpacing) {
ForEach(filters.appliedFilters, id: .self) { filter in
AppliedFilterView(filter: filter, type: .default) {
self.contentsMC.updateFilters(newFilters: self.filters)
}
}
}
}
.padding([.top], .filtersPaddingTop)
}
🤯
SwiftUI
🤔🤩😑
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Content List Filters
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
Content List Filters
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Content List Filters
SwiftUI/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI
🤔🤩😑
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Declarative UI framework.
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
“View is a function of state, not a
sequence of events.”
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Off
On
SwiftUI/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
class CheckmarkBox: UIView {
private var isOn: Bool
init(isOn: Bool) {
self.isOn = isOn
super.init(frame: .zero)
setupViews()
}
}
1. Create
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Off
On
class CheckmarkBox: UIView {
private var isOn: Bool
init(isOn: Bool) {
self.isOn = isOn
super.init(frame: .zero)
setupViews()
}
}
1. Create 2. Configure
SwiftUI/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Off
On
class CheckmarkBox: UIView {
private var isOn: Bool
init(isOn: Bool) {
self.isOn = isOn
super.init(frame: .zero)
setupViews()
}
}
1. Create 2. Configure
SwiftUI/
3. Respond
Parent
Child
1: Tap
2: Change
3: Inform
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
UIKit
SwiftUI/
Parent
Child
1: Tap
2: Change
3: Inform
😩
Multidirectional
data flow.
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. Create 2. Configure 3. Respond
SwiftUI/
struct CheckmarkView: View {
@State var isOn: Bool = false
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { onView()
} else { offView()
}
}
}
}
?Off
On
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
UIKit
SwiftUI/
SwiftUI
Parent
Child
2: Inform
1: Tap
3: Change
Parent
Child
1: Tap
2: Change
3: Inform
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
SwiftUI/
SwiftUI
Parent
Child
2: Inform
1: Tap
3: Change
🥳
Unidirectional
data flow.
Data Flow~
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
👑👑👑
immutablemutable
Data Flow/
a View is a struct
is a value type
is immutable
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@ObservedObject
@State
@EnvironmentObject
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage own state
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
onView()
var body: some View {
if isOn { onView() }
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
onView()
offView()
var body: some View {
if isOn { onView() }
else { offView() }
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
var body: some View {
if isOn { onView() }
else { offView() }
}
}
onView()
offView()
var body: some View {
Button(action: {
//toggle between on/off
}) {
if isOn { onView() }
else { offView() }
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@State var isOn: Bool = false
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { onView() }
else { offView() }
}
}
onView()
offView()
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
= state; source of truth
describes View
mutates State
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
= state owner; source of truth
Checkmark
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
= state owner; source of truth
Event
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
New State
= state; source of truth
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
struct Lamp: View {
var isOn: Bool
}
struct Room: View {
var isLampOn: Bool
var body: some View {
Lamp(isOn: isLampOn)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
struct Lamp: View {
var isOn: Bool
}
struct Room: View {
@State var isLampOn: Bool
var body: some View {
Lamp(isOn: isLampOn)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
struct Lamp: View {
@Binding var isOn: Bool
}
struct Room: View {
@State var isLampOn: Bool
var body: some View {
Lamp(isOn: isLampOn)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
struct Lamp: View {
@Binding var isOn: Bool
}
struct Room: View {
@State var isLampOn: Bool
var body: some View {
Lamp(isOn: $isLampOn)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
@EnvironmentObject
@ObservedObject
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage your own state
2. @State <> @Binding, to communicate between views
@EnvironmentObject
@ObservedObject
@State
Dynamic View Properties
<> @Binding
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Filters
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
struct TitleCheckbox: View {
@State var isOn: Bool
var name: String
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
struct TitleCheckbox: View {
@State var isOn: Bool
var name: String
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
struct TitleCheckbox: View {
@State var isOn: Bool
var name: String
}
struct Checkbox: View {
@Binding var isOn: Bool
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
struct Checkbox: View {
@Binding var isOn: Bool
}
struct TitleCheckbox: View {
@State var isOn: Bool
var name: String
var body: some View {
CheckboxView(isOn: $isOn)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
= state; source of truth
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
= state; source of truth
Parent
TitleCheckbox
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
= state; source of truth
Parent
TitleCheckbox
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@State @Binding @Binding @Binding<> <> <> <>
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@State @Binding @Binding @Binding<> <> <> <>
@Binding @Binding @Binding<> <> <> <>
@Binding @Binding @Binding<> <> <> <>
@Binding<> <>
@Binding<>
@Binding<>
<>
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Custom controls shouldn’t be using @State.
Data Flow Through SwiftUI
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Custom controls shouldn’t be using @State. *
(* or very, very sparingly)
Data Flow Through SwiftUI
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
FiltersLibrary
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Library Filters
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Library Filters
FiltersState
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Library Filters
FiltersState
applied
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Library Filters
FiltersState
editable
applied
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Library Filters
Close/Apply
areFiltersSame
FiltersState
editable
applied
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@ObservedObject
@State
@EnvironmentObject
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@ObservedObject
@State
@EnvironmentObject
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. @State, to manage a View’s own state
2. @State <> @Binding, to communicate between Views
3. @ObservedObject
@EnvironmentObject
to communicate between a View and its model
<> @ObservableObject
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
class FiltersState {
var applied: [Filter] = []
var all: [Filter] = [] {
var editable: [Filter]
var areFiltersSame: Bool {
return all.elementsEqual(editable)
}
func clearAll() {...}
func update(filter: Filter) {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
class FiltersState: ObservableObject {
var applied: [Filter] = []
var all: [Filter] = []
var editable: [Filter]
var areFiltersSame: Bool {
return all.elementsEqual(editable)
}
func clearAll() {...}
func update(filter: Filter) {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
class FiltersState: ObservableObject {
@Published var applied: [Filter] = []
@Published var all: [Filter] = []
@Published var editable: [Filter]
var areFiltersSame: Bool {
return all.elementsEqual(editable)
}
func clearAll() {...}
func update(filter: Filter) {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
class FiltersState: ObservableObject {
private(set) var objectWillChange = PassthroughSubject<Void, Never>()
@Published var applied: [Filter] = []
@Published var all: [Filter] = []
@Published var editable: [Filter]
var areFiltersSame: Bool {
return all.elementsEqual(editable)
}
func clearAll() {...}
func update(filter: Filter) {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
class FiltersState: ObservableObject {
private(set) var objectWillChange = PassthroughSubject<Void, Never>()
@Published var applied: [Filter] = []
@Published var all: [Filter] = []
@Published var editable: [Filter]
var areFiltersSame: Bool {
return all.elementsEqual(editable)
}
func clearAll () {
objectWillChange.send(())
}
func update(filter: Filter) {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
struct TitleCheckbox: View {
@State var isOn: Bool = false
var name: String
var body: some View {
CheckboxBindingView(isOn: $isOn)
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {…}
}
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Heading
Filters List
Close/Apply
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Heading
FiltersList
FiltersView
FiltersState
Close/Apply
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
FiltersView().environmentObject(state)
FiltersView(state: state)
@ObservedObject
@EnvironmentObject
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
FiltersView().environmentObject(state)
FiltersView(state: state)
@ObservedObject
@EnvironmentObject
🤔
Singleton!?
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView: View {
@EnvironmentObject var state: FiltersState
var body: some View {
return VStack {
Heading()
filters()
button()
}
}
func button() -> ButtonView {...}
func filters() -> some View {...}
}
Heading
FiltersList
Button
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
Data Flow/
struct TitleCheckbox: View {
@State var isOn: Bool
var name: String
var body: some View {...}
}
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox
Checkbox
Data Flow/
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {...}
}
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {...}
}
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView: View {
@EnvironmentObject var state: FiltersState
var body: some View {...}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox(name: name)
TitleCheckbox(isOn: $isOn, name: name)
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView2: View {
@EnvironmentObject var state: FiltersState
var body: some View {...}
private func filters() -> some View {
VStack() {
ForEach(state.editable, id: .self) { filter in
TitleCheckbox(isOn: Binding<Bool> , name: String )
}
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView2: View {
@EnvironmentObject var state: FiltersState
var body: some View {...}
private func filtersList() -> some View {
VStack() {
ForEach(state.editable, id: .self) { filter in
TitleCheckbox(isOn: Binding<Bool> , name: String )
}
}
}
}
filter
TitleCheckbox(isOn: Binding<Bool> , name: String )
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@EnvironmentObject var state: FiltersState
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
@EnvironmentObject var state: FiltersState
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView2: View {
@EnvironmentObject var state: FiltersState
var body: some View {...}
private func filtersList() -> some View {
VStack() {
}
}
}
ForEach($state.editable, id:.self) { filter in
TitleCheckbox(isOn: filter.isOn, name: filter.name)
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct FiltersView2: View {
@EnvironmentObject var state: FiltersState
var body: some View {...}
private func filtersList() -> some View {
VStack() {
}
}
}
ForEach(0..<state.editable.count) { index in
TitleCheckbox(isOn: self.$filters.editable[index].isOn,
name: self.filters.editable[index].name)
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Fatal error: Accessing State<Array<Filter>> outside View.body:
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/
Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Fatal error: Accessing State<Array<Filter>> outside View.body:
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/
Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44
ForEach(0..<state.editable.count) { index in
TitleCheckbox(isOn: self.$state.editable[index].isOn,
name: self.state.editable[index].name)
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
Do not access @State
outride of View.body!
🙅 📵👎
ForEach<Range<Int>, Int, AppliedFilterView> count (2) != its
initial count (0). `ForEach(_:content:)` should only be used
for *constant* data. Instead conform data to `Identifiable` or
use `ForEach(_:id:content:)` and provide an explicit `id`!
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
ForEach(0..<state.editable.count) { index in
TitleCheckbox(isOn: self.$state.editable[index].isOn,
name: self.state.editable[index].name)
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Fatal error: Accessing State<Array<Filter>> outside View.body:
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/
Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Fatal error: Accessing State<Array<Filter>> outside View.body:
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/
Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
🤨
Fatal error: Accessing State<Array<Filter>> outside View.body:
file /BuildRoot/Library/Caches/com.apple.xbs/Sources/
Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
😩
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct TitleCheckbox: View {
@State var filter: Filter
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
😩
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Composing complex interfaces
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
private func filtersList() -> some View {
return VStack {
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(filter: filter)
}
}
}
struct TitleCheckbox: View {
@State var filter: Filter
var body: some View {
Checkbox(filter: $filter)
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
TitleCheckbox(filter: filter)
TitleCheckbox(isOn: $isOn, name: name)
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
TitleCheckbox
Checkbox
FiltersView
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
TitleCheckbox
Checkbox
FiltersView
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
TitleCheckbox
Checkbox
FiltersView
👿
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
TitleCheckbox
Checkbox
FiltersView
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
FiltersView
FiltersState; @EnvironmentObject
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
List
FiltersView
FiltersState; @EnvironmentObject
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
List
FiltersView
FiltersState; @EnvironmentObject
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
List
FiltersView
FiltersState; @EnvironmentObject
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
self.filter.isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
self.filter.isOn.toggle()
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
let index = state.editable.firstIndex(of: filter)!
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
let index = state.editable.firstIndex(of: filter)!
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
self.state.editable[self.index].isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
let index = state.editable.firstIndex(of: filter)!
self.state.editable[self.index].isOn.toggle()
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
self.state.editable[self.index].isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
let index = state.editable.firstIndex(of: filter)!
self.state.editable[self.index].isOn.toggle() 🤪
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct LandmarkDetail: View {
@EnvironmentObject var userData: UserData
var landmark: Landmark
var landmarkIndex: Int {
userData.landmarks.firstIndex(where: { $0.id == landmark.id })!
}
var body: some View {
Button(action: {
self.userData.landmarks[self.landmarkIndex].isFavorite.toggle()
}) {
if self.userData.landmarks[self.landmarkIndex].isFavorite {
Image(systemName: "star.fill")
.foregroundColor(Color.yellow)
} else {
Image(systemName: "star")
.foregroundColor(Color.gray)
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@
var body: some View {
Button(action: {
self.state.editable[self.index].isOn.toggle()
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
@EnvironmentObject var state: FiltersState
let index = state.editable.firstIndex(of: filter)!
self.state.editable[self.index].isOn.toggle()
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@EnvironmentObject var state: FiltersState
var body: some View {
Button(action: {
let index = state.editable.firstIndex(of: filter)!
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
self.state.editable[self.index].isOn.toggle()
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@EnvironmentObject var state: FiltersState
var body: some View {
Button(action: {
let index = state.editable.firstIndex(of: filter)!
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
self.state.editable[self.index].isOn.toggle()
@Binding var filter: Filter
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@EnvironmentObject var state: FiltersState
var body: some View {
Button(action: {
let index = state.editable.firstIndex(of: filter)!
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
let index = state.editable.firstIndex(of: filter)!
self.state.editable[self.index].isOn.toggle()
@Binding var filter: Filter
🤯
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
@Binding var filter: Filter
@EnvironmentObject var state: FiltersState
var body: some View {
Button(action: {
let index = state.editable.firstIndex(of: filter)!
}) {
if filter.isOn { OnView() }
else { OffView() }
}
}
}
let filtered = state.editable.filter { $0.name == filter.name }.first!
let index = state.editable.firstIndex(of: filtered)!
self.state.editable[self.index].isOn.toggle()
@Binding var filter: Filter
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
Not reusable.
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
Not reusable.
Code smells…
let filtered = state.editable.filter { $0.name == filter.name }.first!
let index = state.editable.firstIndex(of: filtered)!
self.state.editable[self.index].isOn.toggle()
🤔
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Checkbox
Not reusable.
Code smells…
let filtered = state.editable.filter { $0.name == filter.name }.first!
let index = state.editable.firstIndex(of: filtered)!
self.state.editable[self.index].isOn.toggle()
🤔
🙅
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1:31
Introduction
1:31
Memory Sizing2
1:31
Optionals & Asserts3
Snapchat
Robinhood
Course Episodes
9:41
Video Playback Speed
1080p
720p
540p
360p
Sign Out
1080pVideo Playback Speed
1080pDownloads Quality
OffSubtitles
Downloads (WiFi only)
Settings
9:41
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct TitleCheckbox: View {
var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
var isOn: Bool
var onChange: (Bool) -> Void
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
struct TitleCheckbox: View {
var isOn: Bool
var name: String
var onChange: (Bool) -> Void
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
struct Checkbox: View {
var isOn: Bool
var onChange: (Bool) -> Void
var body: some View {
Button(action: {
self.onChange(!self.isOn)
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
struct TitleCheckbox: View {
var isOn: Bool
var name: String
var onChange: (Bool) -> Void
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: isOn, onChange: onChange)
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
func filtersList() -> some View {
VStack {
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(isOn: filter.isOn, name: filter.name) { isOn in
guard let index = self.state.editable.firstIndex(of: filter)
else { return }
self.state.editable[index].isOn = isOn
}
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
func filtersList() -> some View {
VStack {
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(isOn: filter.isOn, name: filter.name) { isOn in
guard let index = self.state.editable.firstIndex(of: filter)
else { return }
self.state.editable[index].isOn = isOn
}
}
}
}
Data Flow/
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Data Flow/
Recap
🙌
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
2. SwiftUI VS UIKit
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
2. SwiftUI VS UIKit
3. Passing data between Views (and Models)
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
2. SwiftUI VS UIKit
3. Passing data between Views (and Models)
4. Challenges of data-binding for Lists
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
2. SwiftUI VS UIKit
3. Passing data between Views
4. Challenges of data-binding for Lists
5. Approach the unknown by experimenting
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. What SwiftUI is
2. SwiftUI VS UIKit
3. Passing data between Views
4. Challenges of data-binding for Lists
5. Approach the unknown by experimenting
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
Views
Data Reusable Specific
Constant Enumerated + Binding Identifiable + Binding
Dynamic Identifiable + Callbacks Identifiable + Binding
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(isOn: $filter.isOn, name: filter.name)
}
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(isOn: $filter.isOn, name: filter.name)
}
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
Recap
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
ForEach(state.editable, id:.self) { filter in
TitleCheckbox(isOn: $filter.isOn, name: filter.name)
}
struct TitleCheckbox: View {
@Binding var isOn: Bool
var name: String
var body: some View {
HStack {
TitleText(text: name)
Spacer()
Checkbox(isOn: $isOn)
}
}
}
struct Checkbox: View {
@Binding var isOn: Bool
var body: some View {
Button(action: {
self.isOn.toggle()
}) {
if isOn { OnView() }
else { OffView() }
}
}
}
What Now?
🙌
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
1. Conference repo https://github.com/leamars/trySwift2019
2. UIKit translation to SwiftUI https://goshdarnswiftui.com
3. Facebook iOS Components: https://youtu.be/XhXC4SKOGfQ
4. Jetpack Compose: https://youtu.be/VsStyq4Lzxo
5. @hellosunschein on Twitter
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
What Now
Thank You!
🥳🙏👻
try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Connecting Connect with Spring Boot
Connecting Connect with Spring BootConnecting Connect with Spring Boot
Connecting Connect with Spring Boot
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Webdriver io presentation
Webdriver io presentationWebdriver io presentation
Webdriver io presentation
 
Webdriver.io
Webdriver.io Webdriver.io
Webdriver.io
 
Selenium
SeleniumSelenium
Selenium
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Selenium Concepts
Selenium ConceptsSelenium Concepts
Selenium Concepts
 
Spring andspringboot training
Spring andspringboot trainingSpring andspringboot training
Spring andspringboot training
 
[오픈소스컨설팅]Java Performance Tuning
[오픈소스컨설팅]Java Performance Tuning[오픈소스컨설팅]Java Performance Tuning
[오픈소스컨설팅]Java Performance Tuning
 
Selenium WebDriver Tutorial For Beginners | What Is Selenium WebDriver | Sele...
Selenium WebDriver Tutorial For Beginners | What Is Selenium WebDriver | Sele...Selenium WebDriver Tutorial For Beginners | What Is Selenium WebDriver | Sele...
Selenium WebDriver Tutorial For Beginners | What Is Selenium WebDriver | Sele...
 
Java Spring
Java SpringJava Spring
Java Spring
 
Automation Testing by Selenium Web Driver
Automation Testing by Selenium Web DriverAutomation Testing by Selenium Web Driver
Automation Testing by Selenium Web Driver
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework
 
Selenium WebDriver
Selenium WebDriverSelenium WebDriver
Selenium WebDriver
 
Selenium WebDriver with Java
Selenium WebDriver with JavaSelenium WebDriver with Java
Selenium WebDriver with Java
 
Selenium with java
Selenium with javaSelenium with java
Selenium with java
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Selenium
SeleniumSelenium
Selenium
 
Spring & hibernate
Spring & hibernateSpring & hibernate
Spring & hibernate
 
Introduction to Selenium Automation
Introduction to Selenium AutomationIntroduction to Selenium Automation
Introduction to Selenium Automation
 

Último

1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
AldoGarca30
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
HenryBriggs2
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
Epec Engineered Technologies
 

Último (20)

AIRCANVAS[1].pdf mini project for btech students
AIRCANVAS[1].pdf mini project for btech studentsAIRCANVAS[1].pdf mini project for btech students
AIRCANVAS[1].pdf mini project for btech students
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
1_Introduction + EAM Vocabulary + how to navigate in EAM.pdf
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdf
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
Computer Networks Basics of Network Devices
Computer Networks  Basics of Network DevicesComputer Networks  Basics of Network Devices
Computer Networks Basics of Network Devices
 
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
scipt v1.pptxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
Theory of Time 2024 (Universal Theory for Everything)
Theory of Time 2024 (Universal Theory for Everything)Theory of Time 2024 (Universal Theory for Everything)
Theory of Time 2024 (Universal Theory for Everything)
 

SwiftUI For Production | try! Swift 2019

  • 1. SwiftUI for Production try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 2. 🥰 Like SwiftUI? try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 3. 🛠 Used SwiftUI? try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 4. 🥳 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 5. 🥰 + try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 6. SwiftUI 🤔🤩😑 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 7.
  • 8. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/ Where the compiler thinks the problem is. Where the problem actually is.
  • 9. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/
  • 10. List { ForEach(contents, id: .id) { partialContent in NavigationLink(destination: ContentListingView() { CardView(model: CardViewModel.transform(partialContent)) .listRowBackground(self.bgColor) .background(self.bgColor) } .listRowBackground(self.bgColor) .background(self.bgColor) } .listRowBackground(self.bgColor) .background(self.bgColor) ??? How to !@#$ change the BG color of a table view?!
  • 11. private func filtersView() -> some View { ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: .filterSpacing) { ForEach(filters.appliedFilters, id: .self) { filter in AppliedFilterView(filter: filter, type: .default) { self.contentsMC.updateFilters(newFilters: self.filters) } } } } .padding([.top], .filtersPaddingTop) }
  • 12. private func filtersView() -> some View { ScrollView(.horizontal, showsIndicators: false) { HStack(alignment: .top, spacing: .filterSpacing) { ForEach(filters.appliedFilters, id: .self) { filter in AppliedFilterView(filter: filter, type: .default) { self.contentsMC.updateFilters(newFilters: self.filters) } } } } .padding([.top], .filtersPaddingTop) } 🤯
  • 13. SwiftUI 🤔🤩😑 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 14. Content List Filters try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/
  • 15. Content List Filters try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/
  • 16. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Content List Filters SwiftUI/ try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 17. SwiftUI 🤔🤩😑 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 18. Declarative UI framework. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/
  • 19. “View is a function of state, not a sequence of events.” try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/
  • 20. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Off On SwiftUI/
  • 21. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/ class CheckmarkBox: UIView { private var isOn: Bool init(isOn: Bool) { self.isOn = isOn super.init(frame: .zero) setupViews() } } 1. Create
  • 22. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Off On class CheckmarkBox: UIView { private var isOn: Bool init(isOn: Bool) { self.isOn = isOn super.init(frame: .zero) setupViews() } } 1. Create 2. Configure SwiftUI/
  • 23. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Off On class CheckmarkBox: UIView { private var isOn: Bool init(isOn: Bool) { self.isOn = isOn super.init(frame: .zero) setupViews() } } 1. Create 2. Configure SwiftUI/ 3. Respond Parent Child 1: Tap 2: Change 3: Inform
  • 24. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein UIKit SwiftUI/ Parent Child 1: Tap 2: Change 3: Inform 😩 Multidirectional data flow.
  • 25. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. Create 2. Configure 3. Respond SwiftUI/ struct CheckmarkView: View { @State var isOn: Bool = false var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { onView() } else { offView() } } } } ?Off On
  • 26. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein UIKit SwiftUI/ SwiftUI Parent Child 2: Inform 1: Tap 3: Change Parent Child 1: Tap 2: Change 3: Inform
  • 27. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein SwiftUI/ SwiftUI Parent Child 2: Inform 1: Tap 3: Change 🥳 Unidirectional data flow.
  • 28. Data Flow~ try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 👑👑👑
  • 30. a View is a struct is a value type is immutable Data Flow/ try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 31. Data Flow/ try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @ObservedObject @State @EnvironmentObject
  • 32. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage own state Data Flow/
  • 33. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox Data Flow/
  • 34. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein onView() var body: some View { if isOn { onView() } } } Data Flow/
  • 35. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein onView() offView() var body: some View { if isOn { onView() } else { offView() } } } Data Flow/
  • 36. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein var body: some View { if isOn { onView() } else { offView() } } } onView() offView() var body: some View { Button(action: { //toggle between on/off }) { if isOn { onView() } else { offView() } } } Data Flow/
  • 37. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @State var isOn: Bool = false var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { onView() } else { offView() } } } onView() offView() Data Flow/
  • 38. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox = state; source of truth describes View mutates State Data Flow/
  • 39. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 40. = state owner; source of truth Checkmark try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 41. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein = state owner; source of truth Event Data Flow/
  • 42. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein New State = state; source of truth Data Flow/
  • 43. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views Data Flow/
  • 44. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views struct Lamp: View { var isOn: Bool } struct Room: View { var isLampOn: Bool var body: some View { Lamp(isOn: isLampOn) } } Data Flow/
  • 45. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views struct Lamp: View { var isOn: Bool } struct Room: View { @State var isLampOn: Bool var body: some View { Lamp(isOn: isLampOn) } } Data Flow/
  • 46. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views struct Lamp: View { @Binding var isOn: Bool } struct Room: View { @State var isLampOn: Bool var body: some View { Lamp(isOn: isLampOn) } } Data Flow/
  • 47. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views struct Lamp: View { @Binding var isOn: Bool } struct Room: View { @State var isLampOn: Bool var body: some View { Lamp(isOn: $isLampOn) } } Data Flow/
  • 48. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views @EnvironmentObject @ObservedObject Data Flow/
  • 49. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage your own state 2. @State <> @Binding, to communicate between views @EnvironmentObject @ObservedObject @State Dynamic View Properties <> @Binding Data Flow/
  • 50. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Filters Data Flow/
  • 51. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 52. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox Data Flow/
  • 53. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox struct TitleCheckbox: View { @State var isOn: Bool var name: String } Data Flow/
  • 54. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox struct TitleCheckbox: View { @State var isOn: Bool var name: String } Data Flow/
  • 55. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox struct TitleCheckbox: View { @State var isOn: Bool var name: String } struct Checkbox: View { @Binding var isOn: Bool } Data Flow/
  • 56. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox struct Checkbox: View { @Binding var isOn: Bool } struct TitleCheckbox: View { @State var isOn: Bool var name: String var body: some View { CheckboxView(isOn: $isOn) } } Data Flow/
  • 57. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox = state; source of truth Data Flow/
  • 58. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 59. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein = state; source of truth Parent TitleCheckbox Checkbox Data Flow/
  • 60. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein = state; source of truth Parent TitleCheckbox Checkbox Data Flow/
  • 61. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @State @Binding @Binding @Binding<> <> <> <> Data Flow/
  • 62. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @State @Binding @Binding @Binding<> <> <> <> @Binding @Binding @Binding<> <> <> <> @Binding @Binding @Binding<> <> <> <> @Binding<> <> @Binding<> @Binding<> <> Data Flow/
  • 63. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Custom controls shouldn’t be using @State. Data Flow Through SwiftUI Data Flow/
  • 64. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Custom controls shouldn’t be using @State. * (* or very, very sparingly) Data Flow Through SwiftUI Data Flow/
  • 65. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein FiltersLibrary Data Flow/
  • 66. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Library Filters Data Flow/
  • 67. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Library Filters FiltersState Data Flow/
  • 68. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Library Filters FiltersState applied Data Flow/
  • 69. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Library Filters FiltersState editable applied Data Flow/
  • 70. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Library Filters Close/Apply areFiltersSame FiltersState editable applied Data Flow/
  • 71. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @ObservedObject @State @EnvironmentObject Data Flow/
  • 72. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @ObservedObject @State @EnvironmentObject Data Flow/
  • 73. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. @State, to manage a View’s own state 2. @State <> @Binding, to communicate between Views 3. @ObservedObject @EnvironmentObject to communicate between a View and its model <> @ObservableObject Data Flow/
  • 74. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein class FiltersState { var applied: [Filter] = [] var all: [Filter] = [] { var editable: [Filter] var areFiltersSame: Bool { return all.elementsEqual(editable) } func clearAll() {...} func update(filter: Filter) {...} } Data Flow/
  • 75. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein class FiltersState: ObservableObject { var applied: [Filter] = [] var all: [Filter] = [] var editable: [Filter] var areFiltersSame: Bool { return all.elementsEqual(editable) } func clearAll() {...} func update(filter: Filter) {...} } Data Flow/
  • 76. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein class FiltersState: ObservableObject { @Published var applied: [Filter] = [] @Published var all: [Filter] = [] @Published var editable: [Filter] var areFiltersSame: Bool { return all.elementsEqual(editable) } func clearAll() {...} func update(filter: Filter) {...} } Data Flow/
  • 77. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein class FiltersState: ObservableObject { private(set) var objectWillChange = PassthroughSubject<Void, Never>() @Published var applied: [Filter] = [] @Published var all: [Filter] = [] @Published var editable: [Filter] var areFiltersSame: Bool { return all.elementsEqual(editable) } func clearAll() {...} func update(filter: Filter) {...} } Data Flow/
  • 78. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein class FiltersState: ObservableObject { private(set) var objectWillChange = PassthroughSubject<Void, Never>() @Published var applied: [Filter] = [] @Published var all: [Filter] = [] @Published var editable: [Filter] var areFiltersSame: Bool { return all.elementsEqual(editable) } func clearAll () { objectWillChange.send(()) } func update(filter: Filter) {...} } Data Flow/
  • 79. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox struct TitleCheckbox: View { @State var isOn: Bool = false var name: String var body: some View { CheckboxBindingView(isOn: $isOn) } } struct Checkbox: View { @Binding var isOn: Bool var body: some View {…} } Checkbox Data Flow/
  • 80. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 81. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Heading Filters List Close/Apply Data Flow/
  • 82. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Heading FiltersList FiltersView FiltersState Close/Apply Data Flow/
  • 83. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein FiltersView().environmentObject(state) FiltersView(state: state) @ObservedObject @EnvironmentObject Data Flow/
  • 84. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein FiltersView().environmentObject(state) FiltersView(state: state) @ObservedObject @EnvironmentObject 🤔 Singleton!? Data Flow/
  • 85. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView: View { @EnvironmentObject var state: FiltersState var body: some View { return VStack { Heading() filters() button() } } func button() -> ButtonView {...} func filters() -> some View {...} } Heading FiltersList Button Data Flow/
  • 86. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox Data Flow/ struct TitleCheckbox: View { @State var isOn: Bool var name: String var body: some View {...} }
  • 87. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox Checkbox Data Flow/ struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View {...} }
  • 88. struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View {...} } try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView: View { @EnvironmentObject var state: FiltersState var body: some View {...} } Data Flow/
  • 89. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox(name: name) TitleCheckbox(isOn: $isOn, name: name) Data Flow/
  • 90. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView2: View { @EnvironmentObject var state: FiltersState var body: some View {...} private func filters() -> some View { VStack() { ForEach(state.editable, id: .self) { filter in TitleCheckbox(isOn: Binding<Bool> , name: String ) } } } } Data Flow/
  • 91. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView2: View { @EnvironmentObject var state: FiltersState var body: some View {...} private func filtersList() -> some View { VStack() { ForEach(state.editable, id: .self) { filter in TitleCheckbox(isOn: Binding<Bool> , name: String ) } } } } filter TitleCheckbox(isOn: Binding<Bool> , name: String ) Data Flow/
  • 92. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @EnvironmentObject var state: FiltersState Data Flow/
  • 93. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein @EnvironmentObject var state: FiltersState Data Flow/
  • 94. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView2: View { @EnvironmentObject var state: FiltersState var body: some View {...} private func filtersList() -> some View { VStack() { } } } ForEach($state.editable, id:.self) { filter in TitleCheckbox(isOn: filter.isOn, name: filter.name) } Data Flow/
  • 95. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct FiltersView2: View { @EnvironmentObject var state: FiltersState var body: some View {...} private func filtersList() -> some View { VStack() { } } } ForEach(0..<state.editable.count) { index in TitleCheckbox(isOn: self.$filters.editable[index].isOn, name: self.filters.editable[index].name) } Data Flow/
  • 96. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Fatal error: Accessing State<Array<Filter>> outside View.body: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/ Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44 Data Flow/
  • 97. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Fatal error: Accessing State<Array<Filter>> outside View.body: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/ Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44 ForEach(0..<state.editable.count) { index in TitleCheckbox(isOn: self.$state.editable[index].isOn, name: self.state.editable[index].name) } Data Flow/
  • 98. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/ Do not access @State outride of View.body! 🙅 📵👎
  • 99. ForEach<Range<Int>, Int, AppliedFilterView> count (2) != its initial count (0). `ForEach(_:content:)` should only be used for *constant* data. Instead conform data to `Identifiable` or use `ForEach(_:id:content:)` and provide an explicit `id`! try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein ForEach(0..<state.editable.count) { index in TitleCheckbox(isOn: self.$state.editable[index].isOn, name: self.state.editable[index].name) } Data Flow/
  • 100. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Fatal error: Accessing State<Array<Filter>> outside View.body: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/ Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44 Data Flow/
  • 101. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Fatal error: Accessing State<Array<Filter>> outside View.body: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/ Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44 Data Flow/
  • 102. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 🤨 Fatal error: Accessing State<Array<Filter>> outside View.body: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/ Monoceros_Sim/Monoceros-24.4/Core/State.swift, line 44 Data Flow/
  • 103. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } Data Flow/
  • 104. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } 😩 Data Flow/
  • 105. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct TitleCheckbox: View { @State var filter: Filter var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } 😩 Data Flow/
  • 106. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Composing complex interfaces Data Flow/
  • 107. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein private func filtersList() -> some View { return VStack { ForEach(state.editable, id:.self) { filter in TitleCheckbox(filter: filter) } } } struct TitleCheckbox: View { @State var filter: Filter var body: some View { Checkbox(filter: $filter) } } Data Flow/
  • 108. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein TitleCheckbox(filter: filter) TitleCheckbox(isOn: $isOn, name: name) Data Flow/
  • 109. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } Data Flow/
  • 110. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } TitleCheckbox Checkbox FiltersView Data Flow/
  • 111. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } TitleCheckbox Checkbox FiltersView Data Flow/
  • 112. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } TitleCheckbox Checkbox FiltersView 👿 Data Flow/
  • 113. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } TitleCheckbox Checkbox FiltersView Data Flow/
  • 114. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein FiltersView FiltersState; @EnvironmentObject struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } Data Flow/
  • 115. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein List FiltersView FiltersState; @EnvironmentObject struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } Data Flow/
  • 116. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein List FiltersView FiltersState; @EnvironmentObject struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } Data Flow/
  • 117. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein List FiltersView FiltersState; @EnvironmentObject struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } Data Flow/
  • 118. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } Data Flow/
  • 119. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState Data Flow/
  • 120. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { self.filter.isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState self.filter.isOn.toggle() Data Flow/
  • 121. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { let index = state.editable.firstIndex(of: filter)! }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState let index = state.editable.firstIndex(of: filter)! Data Flow/
  • 122. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { self.state.editable[self.index].isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState let index = state.editable.firstIndex(of: filter)! self.state.editable[self.index].isOn.toggle() Data Flow/
  • 123. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { self.state.editable[self.index].isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState let index = state.editable.firstIndex(of: filter)! self.state.editable[self.index].isOn.toggle() 🤪 Data Flow/
  • 124. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct LandmarkDetail: View { @EnvironmentObject var userData: UserData var landmark: Landmark var landmarkIndex: Int { userData.landmarks.firstIndex(where: { $0.id == landmark.id })! } var body: some View { Button(action: { self.userData.landmarks[self.landmarkIndex].isFavorite.toggle() }) { if self.userData.landmarks[self.landmarkIndex].isFavorite { Image(systemName: "star.fill") .foregroundColor(Color.yellow) } else { Image(systemName: "star") .foregroundColor(Color.gray) } } } Data Flow/
  • 125. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @ var body: some View { Button(action: { self.state.editable[self.index].isOn.toggle() }) { if filter.isOn { OnView() } else { OffView() } } } } @EnvironmentObject var state: FiltersState let index = state.editable.firstIndex(of: filter)! self.state.editable[self.index].isOn.toggle() Data Flow/
  • 126. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @EnvironmentObject var state: FiltersState var body: some View { Button(action: { let index = state.editable.firstIndex(of: filter)! }) { if filter.isOn { OnView() } else { OffView() } } } } self.state.editable[self.index].isOn.toggle() Data Flow/
  • 127. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @EnvironmentObject var state: FiltersState var body: some View { Button(action: { let index = state.editable.firstIndex(of: filter)! }) { if filter.isOn { OnView() } else { OffView() } } } } self.state.editable[self.index].isOn.toggle() @Binding var filter: Filter Data Flow/
  • 128. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @EnvironmentObject var state: FiltersState var body: some View { Button(action: { let index = state.editable.firstIndex(of: filter)! }) { if filter.isOn { OnView() } else { OffView() } } } } let index = state.editable.firstIndex(of: filter)! self.state.editable[self.index].isOn.toggle() @Binding var filter: Filter 🤯 Data Flow/
  • 129. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { @Binding var filter: Filter @EnvironmentObject var state: FiltersState var body: some View { Button(action: { let index = state.editable.firstIndex(of: filter)! }) { if filter.isOn { OnView() } else { OffView() } } } } let filtered = state.editable.filter { $0.name == filter.name }.first! let index = state.editable.firstIndex(of: filtered)! self.state.editable[self.index].isOn.toggle() @Binding var filter: Filter Data Flow/
  • 130. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox Data Flow/
  • 131. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox Not reusable. Data Flow/
  • 132. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox Not reusable. Code smells… let filtered = state.editable.filter { $0.name == filter.name }.first! let index = state.editable.firstIndex(of: filtered)! self.state.editable[self.index].isOn.toggle() 🤔 Data Flow/
  • 133. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Checkbox Not reusable. Code smells… let filtered = state.editable.filter { $0.name == filter.name }.first! let index = state.editable.firstIndex(of: filtered)! self.state.editable[self.index].isOn.toggle() 🤔 🙅 Data Flow/
  • 134. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1:31 Introduction 1:31 Memory Sizing2 1:31 Optionals & Asserts3 Snapchat Robinhood Course Episodes 9:41 Video Playback Speed 1080p 720p 540p 360p Sign Out 1080pVideo Playback Speed 1080pDownloads Quality OffSubtitles Downloads (WiFi only) Settings 9:41 Data Flow/
  • 135. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } Data Flow/
  • 136. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct TitleCheckbox: View { var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } Data Flow/
  • 137. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { var isOn: Bool var onChange: (Bool) -> Void var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } } struct TitleCheckbox: View { var isOn: Bool var name: String var onChange: (Bool) -> Void var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } Data Flow/
  • 138. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein struct Checkbox: View { var isOn: Bool var onChange: (Bool) -> Void var body: some View { Button(action: { self.onChange(!self.isOn) }) { if isOn { OnView() } else { OffView() } } } } struct TitleCheckbox: View { var isOn: Bool var name: String var onChange: (Bool) -> Void var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: isOn, onChange: onChange) } } } Data Flow/
  • 139. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein func filtersList() -> some View { VStack { ForEach(state.editable, id:.self) { filter in TitleCheckbox(isOn: filter.isOn, name: filter.name) { isOn in guard let index = self.state.editable.firstIndex(of: filter) else { return } self.state.editable[index].isOn = isOn } } } } Data Flow/
  • 140. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein func filtersList() -> some View { VStack { ForEach(state.editable, id:.self) { filter in TitleCheckbox(isOn: filter.isOn, name: filter.name) { isOn in guard let index = self.state.editable.firstIndex(of: filter) else { return } self.state.editable[index].isOn = isOn } } } } Data Flow/
  • 141. try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Data Flow/
  • 142. Recap 🙌 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 143. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is
  • 144. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is 2. SwiftUI VS UIKit
  • 145. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is 2. SwiftUI VS UIKit 3. Passing data between Views (and Models)
  • 146. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is 2. SwiftUI VS UIKit 3. Passing data between Views (and Models) 4. Challenges of data-binding for Lists
  • 147. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is 2. SwiftUI VS UIKit 3. Passing data between Views 4. Challenges of data-binding for Lists 5. Approach the unknown by experimenting
  • 148. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein 1. What SwiftUI is 2. SwiftUI VS UIKit 3. Passing data between Views 4. Challenges of data-binding for Lists 5. Approach the unknown by experimenting
  • 149. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein Views Data Reusable Specific Constant Enumerated + Binding Identifiable + Binding Dynamic Identifiable + Callbacks Identifiable + Binding
  • 150. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein ForEach(state.editable, id:.self) { filter in TitleCheckbox(isOn: $filter.isOn, name: filter.name) } struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } }
  • 151. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein ForEach(state.editable, id:.self) { filter in TitleCheckbox(isOn: $filter.isOn, name: filter.name) } struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } }
  • 152. Recap try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein ForEach(state.editable, id:.self) { filter in TitleCheckbox(isOn: $filter.isOn, name: filter.name) } struct TitleCheckbox: View { @Binding var isOn: Bool var name: String var body: some View { HStack { TitleText(text: name) Spacer() Checkbox(isOn: $isOn) } } } struct Checkbox: View { @Binding var isOn: Bool var body: some View { Button(action: { self.isOn.toggle() }) { if isOn { OnView() } else { OffView() } } } }
  • 153. What Now? 🙌 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein
  • 154. 1. Conference repo https://github.com/leamars/trySwift2019 2. UIKit translation to SwiftUI https://goshdarnswiftui.com 3. Facebook iOS Components: https://youtu.be/XhXC4SKOGfQ 4. Jetpack Compose: https://youtu.be/VsStyq4Lzxo 5. @hellosunschein on Twitter try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein What Now
  • 155. Thank You! 🥳🙏👻 try! Swift 2019 | Lea Marolt Sonnenschein | @hellosunschein