您现在的位置是:首页 >技术教程 >Xcode 14.3 和 iOS 16.4 为 SwiftUI 带来了哪些新功能?网站首页技术教程

Xcode 14.3 和 iOS 16.4 为 SwiftUI 带来了哪些新功能?

大熊猫侯佩 2024-06-17 11:19:14
简介Xcode 14.3 和 iOS 16.4 为 SwiftUI 带来了哪些新功能?

在这里插入图片描述

0. 概览

今年年初,Apple 推出了最新的 Xcode 14.3 以及对应的 iOS 16.4 。

与此同时,它们对目前最新的 SwiftUI 4.0 也添加了一些新功能:

  • sheet 弹窗后部视图(Interact with a view Behind a sheet)可交互;
  • sheet 弹窗背景透明化;
  • 调整 sheet 弹窗顶角弧度;
  • 控制弹窗内滚动手势优先级;
  • 定制紧密(compact-size )尺寸下 sheet 弹窗大小;
  • Xcode 预览(Preview)模式下对调试输出的支持;

让我们依次来了解一下它们吧。

Let‘s go!!!?


1. sheet 后部视图可交互

在 iOS 16.4 之前,SwiftUI 中 sheet 弹窗后,如果点击其后部的视图会导致弹窗立即被关闭,从而无法与弹窗后部的视图进行交互。

从 iOS 16.4 开始,我们可以为 sheet 弹窗应用 presentationBackgroundInteraction() 方法,以达到不关闭弹窗而与后部视图交互之目的:

@available(iOS 16.4, *)
struct ContentView: View {
    @State private var isPresented = false
    @State private var number = 0
    
    var body: some View {
        ZStack(alignment: .top) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            Button("Sheet") {
                isPresented = true
            }
            .buttonStyle(.borderedProminent)
            .padding()
            
            VStack {
                Button("产生随机数: (number)"){
                    number = Int.random(in: 0..<10000000)
                }
                .foregroundColor(.white)
                .font(.title.weight(.black))
            }.padding(.top, 200)
        }
        .sheet(isPresented: $isPresented) {
            Text("大熊猫侯佩 @ csdn")
                .font(.headline)
                .presentationDetents([.height(120), .medium, .large])
                // 开启后部视图交互
                .presentationBackgroundInteraction(.enabled)
        }
    }
}

在这里插入图片描述

2. sheet 背景透明化

从 iOS 16.4 开始,我们可以为 sheet 弹窗选择透明样式,更好的美化弹出窗口的显示效果。

如下代码所示,我们在 sheet 弹窗上应用了 presentationBackground(_: ) 修改器以实现透明磨砂效果:

@available(iOS 16.4, *)
struct ContentView: View {
    @State private var isSheet = false
    @State private var isSheetTransparency = false
    
    var body: some View {
        ZStack(alignment: .top) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            
            HStack {
                Button("弹出") {
                    isSheet = true
                }
                .sheet(isPresented: $isSheet) {
                    Text("大熊猫侯佩 @ csdn")
                        .font(.headline)
                        .presentationDetents([.height(120), .medium, .large])
                        // 或使用 .background 调用 presentationBackground() 方法效果相同
                        //.presentationBackground(.background)
                }
                
                Spacer()
                
                Button("透明弹出") {
                    isSheetTransparency = true
                }
                .sheet(isPresented: $isSheetTransparency) {
                    Text("大熊猫侯佩 @ csdn")
                        .font(.headline)
                        .presentationDetents([.height(120), .medium, .large])
                        .presentationBackground(.ultraThinMaterial)
                }
            }
            .font(.headline)
            .buttonStyle(.borderedProminent)
            .padding(.top, 200)
            .padding(.horizontal, 50)
        }
    }
}

在这里插入图片描述

3. sheet 顶部弧度调整

感觉 sheet 弹窗顶角生硬无弧度的小伙伴们有福了,从 iOS 16.4 开始,SwiftUI 开始支持调整 sheet 弹出窗口顶角的弧度了。

我们可以使用 .presentationCornerRadius() 修改器来实现这一功能:

@available(iOS 16.4, *)
struct ContentView: View {
    @State private var isSheet = false
    @State private var isSheetRadius = false
    
    var body: some View {
        ZStack(alignment: .top) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            
            HStack {
                Button("弹出") {
                    isSheet = true
                }
                .sheet(isPresented: $isSheet) {
                    Text("大熊猫侯佩 @ csdn")
                        .font(.headline)
                        .presentationDetents(.height(120), .medium, .large])
                }
                
                Spacer()
                
                Button("顶角圆润弧度弹出") {
                    isSheetRadius = true
                }
                .sheet(isPresented: $isSheetRadius) {
                    Text("大熊猫侯佩 @ csdn")
                        .font(.headline)
                        .presentationDetents([.height(120), .medium, .large])
                        .presentationCornerRadius(30.0)
                }
            }
            .font(.headline)
            .buttonStyle(.borderedProminent)
            .padding(.top, 200)
            .padding(.horizontal, 50)
        }
    }
}

在这里插入图片描述

4. sheet 滚动手势优先级调整

在 iOS 16.4 之前,如果我们 sheet 尺寸可变弹窗中包含滚动视图(比如 List,ScrollView 等),当用户在弹窗中滚动将会首先引起弹窗尺寸的改变,而不是其滚动内容的改变。

在 iOS 16.4 之后,我们可以调整 sheet 弹窗滚动手势优先级,以确保首先滚动其内容而不是改变弹窗尺寸。

这是通过 .presentationContentInteraction(.scrolls) 方法来实现的:

@available(iOS 16.4, *)
struct ContentView: View {
    @State private var isSheet = false
    @State private var isSheetScrollable = false
    
    var body: some View {
        
        ZStack(alignment: .top) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            
            
            HStack {
                Button("弹出") {
                    isSheet = true
                }
                .sheet(isPresented: $isSheet) {
                    VStack(spacing: 16) {
                        Text("大熊猫侯佩 @ csdn")
                            .font(.headline)
                        List(0..<50, id: .self){ i in
                            Text("Item (i)")
                                .font(.subheadline)
                        }
                        .listStyle(.plain)
                    }
                    .padding()
                    .presentationDetents([.height(120), .medium, .large])
                }
                
                Spacer()
                
                Button("滚动高优先级弹出") {
                    isSheetScrollable = true
                }
                .sheet(isPresented: $isSheetScrollable) {
                    VStack(spacing: 16) {
                        Text("大熊猫侯佩 @ csdn")
                            .font(.headline)
                        List(0..<50, id: .self){ i in
                            Text("Item (i)")
                                .font(.subheadline)
                        }
                        .listStyle(.plain)
                    }
                    .padding()
                    .presentationDetents([.height(120), .medium, .large])
                    .presentationContentInteraction(.scrolls)
                }
            }
            .font(.headline)
            .buttonStyle(.borderedProminent)
            .padding(.top, 200)
            .padding(.horizontal, 50)
        }
    }
}

在这里插入图片描述

5. 定制 sheet 在紧密尺寸下的大小

在 iOS 16.4 之前,如果在 iPhone 横屏时 sheet 弹窗,则弹出窗口将会铺满整个屏幕。

从 iOS 16.4 开始,我们可以为弹窗应用新的 .presentationCompactAdaptation(_: ) 修改器来改变横屏时弹窗的大小:

struct SheetView: View {
    @Environment(.dismiss) var dismiss
    
    var body: some View {
        VStack(spacing: 16) {
            Text("大熊猫侯佩 @ csdn")
            Button("关闭"){
                dismiss()
            }
        }
    }
}

@available(iOS 16.4, *)
struct ContentView: View {
    @State private var isSheet = false
    @State private var isSheetCompactSizeCustom = false
    
    var body: some View {
                
        ZStack(alignment: .top) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            
            HStack {
                Button("弹出") {
                    isSheet = true
                }
                .sheet(isPresented: $isSheet) {
                    SheetView()
                        .padding()
                        .frame(width: 200)
                        .presentationDetents([.height(200), .medium, .large])
                }
                
                Spacer()
                
                Button("自定义尺寸弹出") {
                    isSheetCompactSizeCustom = true
                }
                .sheet(isPresented: $isSheetCompactSizeCustom) {
                    VStack(spacing: 16) {
                        Text("大熊猫侯佩 @ csdn")
                    }
                    .padding()
                    .frame(width: 350)
                    .presentationDetents([.height(200), .medium, .large])
                    .presentationCompactAdaptation(.sheet)
                }
            }
            .font(.headline)
            .buttonStyle(.borderedProminent)
            .padding(.top, 200)
            .padding(.horizontal, 50)
        }
    }
}

在这里插入图片描述

6. Xcode 预览模式对调试输出的支持

Xcode 14.3 之前,我们在预览(Preview)模式中测试 SwiftUI 界面功能时无法观察调试语句( print 等方法)的输出结果,必须在模拟器或真机中运行才可以在 Xcode 底部调试小窗口中看到 print() 等方法的输出。

从 Xcode 14.3 开始,以预览模式运行 App 时也可以在调试窗口中看到调试语句的输出了,真是太方便了:

@available(iOS 16.4, *)
struct ContentView: View {
    
    var body: some View {
                
        ZStack(alignment: .center) {
            Rectangle()
                .fill(Gradient(colors: [.red,.green]).opacity(0.66))
                .ignoresSafeArea()
            
            Button("显示 debug 输出") {
                print("显示随机数: (Int.random(in: 0..<10000000))")
            }
        }
    }
}

在这里插入图片描述

7. 总结

在本篇博文中,我们介绍了在 Xcode 14.3 和 iOS 16.4 中 SwiftUI 为开发者带来的新方法和新功能,解决了诸多燃眉之急的问题,小伙伴们不想赶快尝试一下吗??

感谢观赏,再会!?

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。