WWDC21 新发布 SwiftUI 的十大新功能

WWDC21 终于来了,SwiftUI 的更新版本有很多新的东西。我很高兴与您分享我心愿单上的许多物品终于到货了。在这篇文章中,我将尝试为您总结今年 SwiftUI 的重要新增功能。

1. 列表

该列表视图是在我们的应用中最普遍的观点。该列表视图中管理UITableView的引擎盖下,但没有暴露的所有强大功能的UITableView至今。现在我们有视图修饰符,可以显示部分和单元格中分隔符和色调颜色的样式选项。让我们看看如何使用它们。

struct ContentView: View {
    @State private var messages: [String] = [
        "Hello", "World"
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach(messages, id: \.self) { message in
                    Text(message)
                }
            }
            .listRowSeparator(.visible, edges: .all)
            .listSectionSeparator(.visible, edges: .all)
            .listSectionSeparatorTint(Color.purple)
            .listRowSeparatorTint(Color.red)
            .navigationTitle("Messages")
        }
    }
}

SwiftUI 还提供了新的swipeActions视图修饰符,我们可以使用它来将可滑动操作附加到列表中的视图。

struct ContentView: View {
    @State private var messages: [String] = [
        "Hello", "World"
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach(messages, id: \.self) { message in
                    Text(message)
                        .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                            Button("Remove", role: .destructive) {
                                messages.removeAll { $0 == message }
                            }
                        }
                        .swipeActions(edge: .leading, allowsFullSwipe: true) {
                            Button("Copy") {
                                messages.append(message)
                            }
                        }
                }
            }.navigationTitle("Messages")
        }
    }
}

正如你在上面的例子中看到的,我们还有一个新的ButtonRole枚举,它允许为按钮指定一个角色,它可以是破坏性的或取消的。

2. 下拉刷新

我曾经在可以更新或重新获取内容的屏幕中使用下拉刷新手势。SwiftUI 提供了新的可刷新视图修饰符,我们可以使用它来附加下拉刷新手势和用户启用手势后 SwiftUI 运行的回调。

struct ContentView: View {
    @State private var messages: [String] = [
        "Hello", "World"
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach(messages, id: \.self) { message in
                    Text(message)
                }
            }.refreshable {
                messages.append("!!!")
            }
            .navigationTitle("Messages")
        }
    }
}

3. 搜索

我在 SwiftUI 中真正错过的另一件事是SearchBar和SearchController的功能。幸运的是,这次 SwiftUI 迭代包含了全新的视图修饰符集合,可实现强大的搜索功能。

struct ContentView: View {
    @State private var query: String = ""
    @State private var messages: [String] = [
        "Hello", "World"
    ]

    var body: some View {
        NavigationView {
            List {
                ForEach(messages, id: \.self) { message in
                    Text(message)
                }
            }
            .searchable("Search term", text: $query, placement: .automatic)
            .onChange(of: query) { print($0) }
            .navigationTitle("Messages")
        }
    }

4. 异步图像 AsyncImage

我没想到的是新的AsyncImage视图。AsyncImage视图允许您使用URLSession下载和呈现远程图像。它提供了一个非常可爱的 API,非常易于使用。让我们来看看它。

struct Post: Hashable {
    let image: URL
    let title: String
    let content: String
}

struct PostView: View {
    let post: Post

    var body: some View {
        HStack {
            AsyncImage(url: post.image)
            VStack {
                Text(post.title)
                Text(post.content)
                    .foregroundColor(.secondary)
            }
        }
    }
}

5. 文本和属性字符串

Swift Foundation 有一个新的AttributedString类型,并且 SwiftUI 开箱即用地支持它。您现在可以将AttributedString的实例传递给Text视图以显示它。这里一个有趣的细节是能够使用新的AttributedString显示降价内容。

struct PostView: View {
    let post: Post

    var markdown: AttributedString {
        try! AttributedString(markdown: post.content)
    }

    var body: some View {
        HStack {
            AsyncImage(url: post.image)
            VStack {
                Text(post.title)
                Text(markdown)
            }
        }
    }
}
struct ContentView: View {
    var body: some View {
        Text("**Happy WWDC21**")
    }
}

6. 焦点管理 @FocusState

最后,SwiftUI 为我们提供了一种在视图中管理焦点的方法。有全新的 @FocusState属性包装器和一个聚焦视图修饰符,我们可以使用它们来切换第一响应者。

struct LoginForm: View {
    enum Field: Hashable {
        case usernameField
        case passwordField
    }

    @State private var username = ""
    @State private var password = ""
    @FocusState private var focusedField: Field?

    var body: some View {
        VStack {
            TextField("Username", text: $username)
                .focused($focusedField, equals: .usernameField)

            SecureField("Password", text: $password)
                .focused($focusedField, equals: .passwordField)

            Button("Sign In") {
                if username.isEmpty {
                    focusedField = .usernameField
                } else if password.isEmpty {
                    focusedField = .passwordField
                } else {
                    handleLogin(username, password)
                }
            }
        }
    }
}

7. Canvas

SwiftUI Canvas是一种新方法,可以更好地控制较低级别的绘图基元。它是现代的、GPU 加速的drawRect等价物。我们可以使用Canvas使用Path绘制形状。我们还可以绘制图像、文本和其他 SwiftUI 视图。

struct ContentView: View {
    var body: some View {
        Canvas { context, size in
            context.fill(
                Circle().path(in: .init(origin: .zero, size: size)),
                with: .color(.green)
            )
        }
    }
}

8. 材料 Material

iOS 提供了材质或模糊效果,可以创建半透明效果,您可以使用它来唤起深度感。材料的效果让视图和控件暗示背景内容,而不会分散前景内容的注意力。我们无法访问以前版本的 SwiftUI 中的材料。幸运的是,新版本的 SwiftUI 为我们提供了从超薄到超厚以及语义条材料的全系列物理材料。

ZStack {
    Color.teal
    Label("Flag", systemImage: "flag.fill")
        .padding()
        .background(.regularMaterial)
}

9. 时间线视图 TimelineView

TimelineView是另一个全新的 SwiftUI 视图。通常,SwiftUI 仅在环境或状态更改期间更新视图。在TimelineView 的情况下,SwiftUI 会根据您提供的时间表更新它。在构建时钟或锻炼应用程序时它可能非常有用。

TimelineView(PeriodicTimelineSchedule(from: startDate, by: 1)) { context in
    AnalogTimerView(date: context.date)
}

10. 还有许多其他值得一提的附加功能

例如全新的 Accessibility Rotors API,新的SectionedFetchRequest属性包装器,允许您向 Core Data 发出分段请求,等等。

加入我们一起学习SwiftUI

QQ:3365059189
SwiftUI技术交流QQ群:518696470
教程网站:www.openswiftui.com

发表回复