阅读 510

iOS 14 SwiftUI中的新增功能

大更新

NavigationView {
    Text("Hello, World!").padding()
        .navigationTitle("SwiftUI")
        .toolbar {
            ToolbarItem(placement: .bottomBar) {
                Button("Press Me") {
                    print("Pressed")
                }
            }
        }
}
#如果想添加多个button
ToolbarItem(placement: .bottomBar) {
    HStack {
        Button("First") {
            print("Pressed")
        }

        Button("Second") {
            print("Pressed")
        }
    }
}
复制代码
#在iPadOS中。这添加三个视图就可以拆分视图
struct ContentView: View {
    var body: some View {
        NavigationView {
            Sidebar()
            PrimaryView()
            DetailView()
        }
    }
}
复制代码
#如果需要显示列表的话使用`SidebarListStyle()`
struct Sidebar: View {
    var body: some View {
        List(1..<100) { i in
            Text("Row \(i)")
        }
        .listStyle(SidebarListStyle())
    }
}
复制代码

改进

struct ContentView: View {
    let colors: [Color] = [.red, .green, .blue]

    var body: some View {
        ScrollView {
            ScrollViewReader { value in
                Button("Jump to #8") {
                    value.scrollTo(8)
                }

                ForEach(0..<10) { i in
                    Text("Example \(i)")
                        .frame(width: 300, height: 300)
                        .background(colors[i % colors.count])
                        .id(i)
                }
            }
        }
    }
}

复制代码
import MapKit
import SwiftUI

struct ContentView: View {
    @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))

    var body: some View {
        Map(coordinateRegion: $region)
    }
}
复制代码
struct ContentView: View {
    @State private var downloadAmount = 0.0
    let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack {
            ProgressView("Downloading…", value: downloadAmount, total: 100)
        }
        .onReceive(timer) { _ in
            if downloadAmount < 100 {
                downloadAmount += 2
            }
        }
    }
}
复制代码
VideoPlayer(player: AVPlayer(url:  URL(string: "video.url")!)) {
    VStack {
        Text("Watermark")
            .font(.caption)
            .foregroundColor(.white)
            .background(Color.black.opacity(0.7))
            .clipShape(Capsule())
        Spacer()
    }
}
复制代码
struct SwiftUITestApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                HomeView()
                AccountView()
                ProfileView()
                SettingsView()
            }
            .tabViewStyle(PageTabViewStyle())
        }
    }
}
复制代码
struct ContentView: View {
    @Namespace private var animation
    @State private var isZoomed = false

    var frame: CGFloat {
        isZoomed ? 300 : 44
    }

    var body: some View {
        VStack {
            Spacer()

            VStack {
                HStack {
                    RoundedRectangle(cornerRadius: 10)
                        .fill(Color.blue)
                        .frame(width: frame, height: frame)
                        .padding(.top, isZoomed ? 20 : 0)

                    if isZoomed == false {
                        Text("Taylor Swift – 1989")
                            .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                            .font(.headline)
                        Spacer()
                    }
                }

                if isZoomed == true {
                    Text("Taylor Swift – 1989")
                        .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                        .font(.headline)
                        .padding(.bottom, 60)
                    Spacer()
                }
            }
            .onTapGesture {
                withAnimation(.spring()) {
                    self.isZoomed.toggle()
                }
            }
            .padding()
            .frame(maxWidth: .infinity)
            .frame(height: isZoomed ? 400 : 60)
            .background(Color(white: 0.9))
        }
    }
}
复制代码
struct Bookmark: Identifiable {
    let id = UUID()
    let name: String
    let icon: String
    var items: [Bookmark]?

    // some example websites
    static let apple = Bookmark(name: "Apple", icon: "1.circle")
    static let bbc = Bookmark(name: "BBC", icon: "square.and.pencil")
    static let swift = Bookmark(name: "Swift", icon: "bolt.fill")
    static let twitter = Bookmark(name: "Twitter", icon: "mic")

    // some example groups
    static let example1 = Bookmark(name: "Favorites", icon: "star", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example2 = Bookmark(name: "Recent", icon: "timer", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example3 = Bookmark(name: "Recommended", icon: "hand.thumbsup", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
}
复制代码
struct ContentView: View {
    let items: [Bookmark] = [.example1, .example2, .example3]

    var body: some View {
        List(items, children: \.items) { row in
            Image(systemName: row.icon)
            Text(row.name)
        }
    }
}
复制代码

新的属性包装器

  • 什么是@AppStorage属性包装器?– UserDefaults轻松读写

SwiftUI有一个专用的属性包装器,用于从中读取值UserDefaults,当值更改时,它将自动重新调用视图的body属性。也就是说,此包装器有效地监视中的键UserDefaults,并且如果该键更改,将刷新您的UI。

struct ContentView: View {
    @AppStorage("username") var username: String = "Anonymous"
    
    var body: some View {
        VStack {
            Text("Welcome, \(username)!")

            Button("Log in") {
                self.username = "@twostraws"
            }
        }
    }
}
复制代码

这里如果更改了username 的字符串 UserDefaults 会立即写入 同时更新视图

UserDefaults.standard.set("@twostraws", forKey: "username")`
复制代码

当我们更改了username 同样会更新

  • 什么是@ScaledMetric属性包装器?–根据“动态类型”设置缩放值
  • 什么是@StateObject属性包装器?–在视图中安全地创建引用类型
  • 什么是@UIApplicationDelegateAdaptor属性包装器?

更多