项目档案

更多组件赢博体育

我们的下一个例子是一个赢博体育程序,将演示如何使用一些SwiftUI组件,我们没有机会在这个过程中覆盖到目前为止。

选项卡导航

这个赢博体育程序演示的第一个新功能是使用选项卡界面的新型导航。在赢博体育程序的底部,你会看到一组三个图标-这些让我们可以通过简单地点击我们想要的屏幕图标轻松地在三个屏幕之间导航。

这个导航结构是在赢博体育的ContentView中设置的,它是赢博体育的主视图:

struct ContentView: View {var body:一些View {TabView {FormDemoView()。tabItem {Label("Form",systemImage: "list.bullet")} DialogDemoView()。tabItem {Label(" dialog ",systemImage: "bubble")} PhotosView()。tabItem {Label("Photos",systemImage:"camera")}}}}

TabView组件的内容列出了可用的选项卡。每个选项卡都是一个视图,由tabItem修改,tabItem描述了如何可视化地显示它。在每种情况下,我们都使用Label()组件来表示项。Label()构造函数中的systemImage参数指定用于标签的图标。

SwiftUI配备了超过6000个图标供选择。查看赢博体育可用图标的最佳方法是使用苹果提供的SF Symbols Mac赢博体育程序。要下载此赢博体育程序,请访问developer.apple.com/sf-symbols。

表单演示

在我们的示例赢博体育程序的三个屏幕中,第一个屏幕演示了Form()组件的使用,以及一些我们还没有机会使用的输入组件。

下面是该屏幕的代码:

struct FormDemoView: View {@State var choseThis = false让meals =[“早餐”,“午餐”,“晚餐”]@State var favoriteMeal =“午餐”@State var rating = 3 var body: some View {Form {Section {Toggle(isOn: $choseThis, label:{Text("Prefer this")})如果choseThis {Text("You chose to Prefer this.")} else {Text("You chose to Prefer that.")}} Section {Picker("Favorite meal",selection:$favoriteMeal) {ForEach(meals,id:\.self) {meal in Text(meal)}}. pickerstyle (.segmented) Text("Your favourite meal is \(favoriteMeal)")} Section {Stepper("Rating",value: $ Rating,in: 1…5)Text("Your rated it \(Rating)")}}}}

Form()是Section()组件的列表。每个部分在表单的灰色背景前显示为带有圆角边框的白色矩形。这在各部分之间创建了视觉分离。这里的三个部分演示了三个新输入元素的使用:Toggle()、Picker()和Stepper()。在每种情况下,我都将输入元素链接到组件将更新的状态变量。

Pickers有几种不同的口味。我在这里使用的样式是分段样式,它一次显示赢博体育选项。如果您从选择器中删除. pickerstyle()修饰符,您将看到另一种样式,它将向用户显示一个可供选择的下拉菜单。

Stepper()允许用户在可接受的整数值范围内上下步进。允许的值范围由构造函数中的in:形参指定。

使用警报和对话框

赢博体育程序中的第二个屏幕演示了警报对话框和工作表的使用。

警报和表单都是模态对话框的实例。模态对话框是响应某些用户操作而弹出的用户界面元素。当对话框可见时,用户被锁定,无法与屏幕上的其他用户界面元素进行交互。

在这个例子中,我将一个警告对话框和一个表单绑定到两个用户界面元素上。第一个例子是将一个警告对话框链接到“Do It!”按钮。当用户单击该按钮时,警报将弹出,并要求他们确认他们真的打算执行此操作。

警报为用户提供了几个按钮,用户可以单击它们来确认操作或取消操作。下面,当我们查看这段代码时,我们会发现,在警报中添加额外的选项,为用户提供更广泛的选择,这是相对容易的。

该表单链接到“更改它!”按钮。当用户单击该按钮时,表单将弹出并要求用户在继续之前提供其他信息。再说一次,表单是一种模态交互,它迫使用户在做其他事情之前做出选择。

表单可以包含几乎无限的组件集,以支持相当复杂的场景。当我们查看下面的代码时,我们将看到这是如何完成的。

下面是第二个屏幕的代码:

struct DialogDemoView:查看{@State var根本没认识到这份工作的艰辛= false @State var showConfirmation = false让颜色=(“红”、“绿色”、“蓝色”@State var favoriteColor =“红色”@State var showSheet = false var身体:一些视图{VStack{垫片()如果根本没认识到这份工作的艰辛= = false{按钮(“做到!”){showConfirmation = true} .buttonStyle (.bordered) .confirmationDialog(“确认”,ispresent: showConfirmation美元){按钮(“OK”){根本没认识到这份工作的艰辛= true}按钮(“取消”,角色:.cancel){}}信息:{Text("Are you sure you want do it?")} else {Text(" you have done it.")} Spacer() Text("Your favorite color is \(favoriteColor .")) Button("Change it!") {showSheet = true} . buttonstyle (. borderdered). sheet(ispresent:$ showSheet) {ColorSheet(choices:colors,selected:favoriteColor,finalChoice:$favoriteColor)} Spacer()}}

这里首先要关注的是实现警报对话框的代码。这是附加在“Do It!”按钮上的修饰符:

.confirmationDialog("Confirm it", ispresent: $showConfirmation) {Button("OK") {didIt = true} Button("Cancel", role: .cancel) {}} message: {Text("Are you sure you want to do it?")

}

因为我们要设置一个警报,我们需要做的第一件事是设置逻辑来决定警报什么时候应该在屏幕上弹出。在本例中,这是通过设置状态变量showConfirmation并将其用于confirmationDialog的ispresenting参数来实现的。如果您查看上面“Do It!”按钮的代码,您将看到“Do It!”按钮将该状态变量变为true,这反过来将导致警报出现。

确认对话框有两个部分,我们在其中设置将显示的按钮和对话框将显示的文本消息。单击这两个按钮中的任何一个都将自动解除警报。此外,我们可以向按钮添加逻辑来做其他事情。在本例中,单击OK按钮将更改另一个状态变量的值。这反过来又会改变屏幕的功能。

下面要看的是生成表单的代码。这是附加在“Change It!”按钮上的修饰符:

.sheet(ispresent:$ showSheet) {ColorSheet(choices:colors,selected:favoriteColor,finalChoice:$favoriteColor)}

这里的代码与警告类似。我们再次使用状态变量showSheet来控制表单是否应该显示。sheet()组件也有一个主体,其中可以包含设置将在工作表中显示的组件的代码。由于大多数工作表比简单的确认对话框更复杂,大多数程序员采用的方法是为整个工作表编写一个自定义组件,然后在工作表的主体中调用该组件。这是我在这里使用的方法。下面是表格主体组件的代码:

struct ColorSheet:查看{@Environment (\ .dismiss)私人var驳回var选择:[String] @State var选择:字符串@Binding var finalChoice:字符串var身体:一些视图{VStack{文本(“选择一种颜色。”)选择器(“最喜欢的颜色”,选择:选择美元){ForEach(选择,id: \ .self){选择文本(选择)}}.pickerStyle (.segmented) HStack{按钮(“取消”){解散()}垫片()按钮(“确认”){finalChoice =选择解散()}}}.padding ()}}

在您在这里看到的主体代码中,我们设置了要显示在工作表上的赢博体育组件。

这里的一个不寻常的元素是解散()函数。您可以看到,它被设置为组件顶部的环境变量,这意味着我们指望系统在工作表运行时自动为我们提供此功能。正如您可能猜到的那样,解散()函数的目的是使工作表消失。我们确保在“确认”按钮和“取消”按钮的代码中都调用了该函数。

这里代码的另一个微妙方面是管理工作表与其父屏幕之间的交互。我显示此工作表的原因是让用户有机会更新屏幕中的一个状态变量,即favoriteColor变量。我们将通过绑定finalChoice让工作表访问该状态变量。当我调用ColorSheet组件时,我向它传递一个对favoriteColor状态变量的引用,并将其链接到finalChoice绑定变量。由于finalChoice是一个绑定,更新它将自动更新它所绑定的favoriteColor状态变量。

处理照片

我们示例赢博体育程序中的第三个屏幕让用户有机会从他们的照片库中选择一张照片。

点击“选择图片”按钮会弹出一个照片选择对话框,允许用户从他们的图库中选择一张照片。

一旦用户选择了一张照片,照片将出现在屏幕上。

下面是这个屏幕的代码。

struct PhotosView:视图{@状态私有var selectedItem: PhotosPickerItem?@State私有var selecteimage:图像?var body: some View {VStack {Spacer() PhotosPicker("Select image", selection: $selectedItem, matching: .images) .buttonStyle(. borderdered) if let image = selectedImage {image.resizable() .scaledToFit() .frame(width: 300, height: 300) Spacer()} else {Spacer() image (systemName:"person").resizable().frame(width: 150,height: 150) Spacer()}} .onChange(of: selectedItem) {Task {if let loaded = try?等待设置selectedItem ?。loadTransferable(type: Image.self) {selecteimage = loaded}}}}}

那个看起来像“Select image”按钮的东西实际上是一个PhotosPicker()组件。单击它会弹出一个提示用户选择图像的工作表。关于用户选择的图像的信息将存储在selectedItem状态变量中。

这里的另一个关键部分是一个更改侦听器,它将在selectedItem状态变量更新时被触发。

.onChange(of: selectedItem){任务{如果让加载=尝试?等待设置selectedItem ?。loadTransferable(type: Image.self) {selecteimage = loaded}}

当用户选择了一个项目后,我们运行一个后台任务来加载选中的图像并将其存储在selecteimage状态变量中。