自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

WWDC 23 之后的 SwiftUI 有哪些新功能

開發(fā) 架構(gòu)
Swift 5.9 引入了宏功能,成為 SwiftUI 數(shù)據(jù)流的核心。SwiftUI 不再使用 Combine?,而是使用新的 Observation? 框架。Observation 框架為我們提供了 Observable 協(xié)議,必須使用它來允許 SwiftUI 訂閱更改并更新視圖。

前言

WWDC 23 已經(jīng)到來,SwiftUI 框架中有很多改變和新增的功能。在本文中將主要介紹 SwiftUI 中數(shù)據(jù)流、動畫、ScrollView、搜索、新手勢等功能的新變化。

數(shù)據(jù)流

Swift 5.9 引入了宏功能,成為 SwiftUI 數(shù)據(jù)流的核心。SwiftUI 不再使用 Combine,而是使用新的 Observation 框架。Observation 框架為我們提供了 Observable 協(xié)議,必須使用它來允許 SwiftUI 訂閱更改并更新視圖。

@Observable
final class Store {
    var products: [String] = []
    var favorites: [String] = []
    
    func fetch() async {
        try? await Task.sleep(nanoseconds: 1_000_000_000)
        // load products
        products = [
            "Product 1",
            "Product 2"
        ]
    }
}

不需要在代碼中遵循 Observable 協(xié)議。相反,可以使用 @Observable 宏來標(biāo)記你的類型,它會自動為符合 Observable 協(xié)議。也不再需要 @Published 屬性包裝器,因為 SwiftUI 視圖會自動跟蹤任何可觀察類型的可用屬性的更改。

struct ProductsView: View {
    @State private var store = Store()
    
    var body: some View {
        List(store.products, id: \.self) { product in
            Text(verbatim: product)
        }
        .task {
            if store.products.isEmpty {
                await store.fetch()
            }
        }
    }
}

以前,有一系列的屬性包裝器,如 State、StateObject、ObservedObject 和 EnvironmentObject,你應(yīng)該了解何時以及為何使用它們。

現(xiàn)在,狀態(tài)管理變得更加簡單。對于值類型(如字符串和整數(shù))和符合 Observable 協(xié)議的引用類型,只需使用 State 屬性包裝器。

struct FavoriteProductsView: View {
    let store: Store
    
    var body: some View {
        List(store.favorites, id: \.self) { product in
            Text(verbatim: product)
        }
    }
}

在上面的示例中,有一個接受 Store 類型的視圖。在之前的 SwiftUI 框架版本中,應(yīng)該使用 @ObservedObject 屬性包裝器來訂閱更改?,F(xiàn)在不需要了,因為 SwiftUI 視圖會自動跟蹤符合 Observable 協(xié)議的類型的更改。

struct EnvironmentViewExample: View {
    @Environment(Store.self) private var store
    
    var body: some View {
        Button("Fetch") {
            Task {
                await store.fetch()
            }
        }
    }
}

struct ProductsView: View {
    @State private var store = Store()
    
    var body: some View {
        List(store.products, id: \.self) { product in
            Text(verbatim: product)
        }
        .task {
            if store.products.isEmpty {
                await store.fetch()
            }
        }
        .toolbar {
            NavigationLink {
                EnvironmentViewExample()
            } label: {
                Text(verbatim: "Environment")
            }
        }
        .environment(store)
    }
}

還可以使用 Environment 屬性包裝器與 environment 視圖修飾符配對,將可觀察類型放入 SwiftUI 環(huán)境中。不需要使用 @EnvironmentObject 屬性包裝器或 environmentObject 視圖修飾符。同樣的 Environment 屬性包裝器現(xiàn)在適用于可觀察類型。

struct BindanbleViewExample: View {
    @Bindable var store: Store
    
    var body: some View {
        List($store.products, id: \.self) { $product in
            TextField(text: $product) {
                Text(verbatim: product)
            }
        }
    }
}

每當(dāng)需要從可觀察類型中提取綁定時,可以使用新的 Bindable 屬性包裝器。

動畫

動畫始終是 SwiftUI 框架中最重要的部分。在 SwiftUI 中輕松實現(xiàn)任何動畫,但之前的框架版本缺少一些現(xiàn)在具有的功能。

struct AnimationExample: View {
    @State private var value = false
    
    var body: some View {
        Text(verbatim: "Hello")
            .scaleEffect(value ? 2 : 1)
            .onTapGesture {
                withAnimation {
                    value.toggle()
                } completion: {
                    print("Animation have finished")
                }
            }
    }
}

如上例所示,我們有了新版本的 withAnimation 函數(shù),允許提供動畫完成處理程序。這是一個很好的補(bǔ)充,現(xiàn)在您可以構(gòu)建階段性動畫。

enum Phase: CaseIterable {
    case start
    case loading
    case finish
    
    var offset: CGFloat {
        // Calculate offset for the particular phase
        switch self {
        case start: 100.0
        case loading: 0.0
        case finish: 50.0
        }
    }
}

struct PhasedAnimationExample: View {
    @State private var value = false
    
    var body: some View {
        PhaseAnimator(Phase.allCases, trigger: value) { phase in
            LoadingView()
                .offset(x: phase.offset)
        } animation: { phase in
            switch phase {
            case .start: .easeIn(duration: 0.3)
            case .loading: .easeInOut(duration: 0.5)
            case .finish: .easeOut(duration: 0.1)
            }
        }
    }
}

SwiftUI 框架引入了新的 PhaseAnimator 視圖,它遍歷階段序列,允許為每個階段提供不同的動畫,并在階段更改時更新內(nèi)容。還有 KeyframeAnimator 視圖,可以使用關(guān)鍵幀來實現(xiàn)動畫。

ScrollView

今年 ScrollView 有了很多優(yōu)秀的新增功能。首先,可以使用 scrollPosition 視圖修飾符來觀察內(nèi)容偏移量。

struct ContentView: View {
    @State private var scrollPosition: Int? = 0
    
    var body: some View {
        ScrollView {
            Button("Scroll") {
                scrollPosition = 80
            }
            
            ForEach(1..<100, id: \.self) { number in
                Text(verbatim: number.formatted())
            }
            .scrollTargetLayout()
        }
        .scrollPosition(id: $scrollPosition)
    }
}

如上例所示,使用 scrollPosition 視圖修飾符將內(nèi)容偏移量綁定到一個狀態(tài)屬性上。每當(dāng)用戶滾動視圖時,它會通過設(shè)置第一個可見視圖的標(biāo)識來更新綁定。還可以通過編程方式滾動到任何視圖,但是,應(yīng)該使用 scrollTargetLayout 視圖修飾符來告訴 SwiftUI 框架在哪里查找標(biāo)識以更新綁定。

struct ContentView: View {
    var body: some View {
        ScrollView {
            ForEach(1..<100, id: \.self) { number in
                Text(verbatim: number.formatted())
            }
            .scrollTargetLayout()
        }
        .scrollTargetBehavior(.paging)
    }
}

可以通過使用 scrollTargetBehavior 視圖修飾符來更改滾動行為。它允許在滾動視圖中啟用分頁。

搜索

與搜索相關(guān)的視圖修飾符也有一些很好的新增功能。例如,可以通過編程方式聚焦到搜索字段。

struct ProductsView: View {
    @State private var store = Store()
    @State private var query = ""
    @State private var scope: Scope = .default
    
    var body: some View {
        List(store.products, id: \.self) { product in
            Text(verbatim: product)
        }
        .task {
            if store.products.isEmpty {
                await store.fetch()
            }
        }
        .searchable(text: $query, isPresented: .constant(true), prompt: "Query")
        .searchScopes($scope, activation: .onTextEntry) {
            Text(verbatim: scope.rawValue)
        }
    }
}

如上例所示,可以使用可搜索視圖修飾符的 isPresented 參數(shù)來顯示/隱藏搜索字段。還可以使用 searchScopes 視圖修飾符的 activation 參數(shù)來定義范圍的可見性邏輯。

新手勢

新增的 RotateGesture 和 MagnifyGesture 使我們能夠跟蹤視圖的旋轉(zhuǎn)和放大。

struct RotateGestureView: View {
    @State private var angle = Angle(degrees: 0.0)

    var rotation: some Gesture {
        RotateGesture()
            .onChanged { value in
                angle = value.rotation
            }
    }

    var body: some View {
        Rectangle()
            .frame(width: 200, height: 200, alignment: .center)
            .rotationEffect(angle)
            .gesture(rotation)
    }
}

新增的小功能

增加了全新的 ContentUnavailableView 類型,當(dāng)需要顯示空視圖時可以使用它。示例如下:

struct ProductsView: View {
    @State private var store = Store()
    
    var body: some View {
        List(store.products, id: \.self) { product in
            Text(verbatim: product)
        }
        .background {
            if store.products.isEmpty {
                ContentUnavailableView("Products list is empty", systemImage: "list.dash")
            }
        }
        .task {
            if store.products.isEmpty {
                await store.fetch()
            }
        }
    }
}

還有新增了新的視圖修飾符,允許調(diào)整列表中的間距??梢允褂?nbsp;listRowSpacing 和 listSectionSpacing 視圖修飾符來設(shè)置列表中所需的間距。EnvironmentValues 結(jié)構(gòu)體包含了一系列與最新平臺更新相關(guān)的新屬性,例如 isActivityFullscreen 和 showsWidgetContainerBackground。Swift Charts 也具有可滾動和可動畫的功能。

#Preview {
    ContentView()
}

還有一個新的 Preview 宏,可以讓我們輕松地為 UIKit 和 SwiftUI 構(gòu)建預(yù)覽,只需幾行代碼。

總結(jié)

SwiftUI 框架中有許多小的新增功能,我們將會繼續(xù)分享。希望能幫到你。

責(zé)任編輯:武曉燕 來源: Swift社區(qū)
相關(guān)推薦

2024-06-25 09:05:09

SwiftUIUIKitEntry

2022-02-16 23:11:04

iOS蘋果功能

2020-09-01 10:16:03

Windows 10Windows 10 微軟

2020-12-07 05:47:47

VCF 4.0虛擬化

2010-04-01 09:03:31

RHEL 5.5

2010-07-23 09:53:29

SQL Server

2010-04-22 10:01:44

Oracle收購SUN

2020-07-08 15:12:29

iOSIpad OS蘋果

2021-08-19 09:37:06

Go 1.17語言架構(gòu)

2015-06-10 16:23:33

WWDC庫克蘋果

2020-02-20 16:30:22

iOS 13.4蘋果iPhone

2010-08-26 15:22:36

DB2新功能

2021-08-02 15:28:58

iOS蘋果系統(tǒng)

2015-08-17 11:30:51

2020-10-24 17:52:10

工業(yè)物聯(lián)網(wǎng)IIOT物聯(lián)網(wǎng)

2020-11-09 07:15:51

Fedora 33WorkstationLinux

2011-02-28 17:41:20

SQL Server

2020-08-16 09:25:21

Windows 10Windows操作系統(tǒng)

2009-06-19 12:53:56

Spring 2.0

2017-11-06 15:05:18

iPhone X功能iOS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號