SwiftUI - 包裝UIView

UIViewRepresentable SwiftUI 尚未能實現,將 UIKit 中已有的部分進行封裝,提供給 SwiftUI 使用 UIViewRepresentable 協議提供了在 SwiftUI 中封裝 UIView 的功能 此協議需要實作2個方法 protocol UIViewRepresentable: View { associatedtype UIViewType: UIView func makeUIView(context: Self.Context) -> Self.UIViewType func updateUIView(_ uiview: Self.UIViewType, context: Self.Context) } makeUIView(context:) 需要返回想要封裝的 UIView 類型,SwiftUI 在創建一個被封裝的 UIView 時會調用此方法 updateUIView(_:, context:) 則在 UIViewRepresentable 中的某個屬性發生變化,SwiftUI 要求更新該 UIKit 部件時被調用 例:在SwiftUI使用UIKit的UIVisualEffectView import SwiftUI import UIKit struct BlurView: UIViewRepresentable { let style: UIBlurEffect.Style func makeUIView(context: UIViewRepresentableContext<BlurView>) -> UIView { let view = UIView(frame: ....

2022-07-17 08:00 · 1 min · Tientien

SwiftUI - ObservableObject

ObservableObject 和 @ObservedObject ObservableObject 是一個 protocol,要求實現協議的類型為 class,有一個需要實作的屬性 objectWillChange。 當數據將要發生改變時,這個屬性用來向外進行「廣播」,它的訂閱者(一般是 View 相關的邏輯)在收到通知後,對 View 進行刷新。 創建遵從 ObservableObject 協議的類別後,實際在 View 裡使用需要將此物件宣告為 @ObservedObject。 範例:點擊按鈕擲骰子 使用 PassthroughSubject 中 send() 方法通知事件將要發生。 PassthroughSubject 於 Combine 框架中,將於後續介紹。 ContentView 中 model 為 reference type,使用 @ObservedObject 將它和 ContentView 關聯起來。當 model 中的屬性 diceState 將要改變,objectWillChange 就會發出事件,使得 body 被調用進行UI刷新。 struct ContentView: View { @ObservedObject private var model = DiceModel() var body: some View { CounterButton(diceState: $model.diceState) } } class DiceModel: ObservableObject { let objectWillChange = PassthroughSubject<Void, Never>() var diceState: DiceState = ....

2022-02-06 18:00 · 2 min · Tientien

SwiftUI - 狀態(State)與綁定(Binding)

屬性包裝、投射屬性 由 @ 修飾的屬性稱為屬性包裝(Property Wrapper)。 @State、@Binding、@ObjectBinding、@EnvironmentObject都是 @propertyWrapper 修飾的 struct。 對一個由 @ 修飾的屬性,在它前面使用 $ 取得的值,被稱為投射屬性(Projection Property)。 並不是所有的 @ 屬性都提供 $ 的投射訪問方式。 @State @State 修飾的屬性會被自動轉換為一對 setter 和 getter 對這個屬性進行賦值的操作,它的 body 會被再次調用,進行 View 的刷新。 但由於是 value type ,在不同物件傳遞時透過複製值,因此經過不同層級底層改變並無法更新頂層的值。 訪問 @State 修飾的屬性,所有調用觸發的都是 wrappedValue。 使用 $ 訪問屬性,取得的是 projectedValue ,為一個 Binding 類型的值。 SwiftUI 中 State 定義的關鍵部分 @propertyWrapper public struct State<Value>: DynamicViewProperty, BindingConvertible { public var value: Value { get nonmutating set } public var wrappedValue: Value { get nonmutating set } public var projectedValue: Binding<Value> { get } init(initialValue value: Value) } 範例:點擊按鈕數字累加點擊次數 struct ContentView: View { @State private var count: Int = 0 var body: some View { Button { self....

2022-02-06 14:15 · 2 min · Tientien

Redux架構

適合 SwiftUI 的架構 Redux 基本概念 App 為一個狀態機,狀態決定用戶介面。 這些狀態(State)都保存在一個 Store 物件中。 View 不能直接操作 State,只能通過發送 Action 的方式間接改變儲存在 Store 中的 State 。 Reducer 接受原有的 State 和發送過來的 Action,生成新的 State。 用新的 State 替換 Store 中原有的狀態,並用新的狀態來驅動更新介面。 Store 應用程式只有一個 Store,用來保存整個應用程式的 State。 可以透過 store.getState() 取得應用程式當前狀態,但不能直接修改。 Action Action 為一個普通的物件,用來描述應用程式發生的事情,把數據傳遞給 Store 的唯一途徑。 Reducer Reducer.reduce(state: action:)是純函數,具體處理狀態的邏輯。 純函數:返回值只由調用時的參數決定,不依賴於任何系統狀態,也不改變其作用域之外的變量狀態的函數。 struct Reducer { static func reduce(state: State, action: Action) -> State { return state.apply(item: action) } }

2022-02-06 09:20 · 1 min · Tientien