SwiftUI:如何使用语义放置呈现多个 ToolbarItem?
SwiftUI: how to present more than one ToolbarItem using semantic placement?
WWDC 2020 SwiftUI 演讲提到了一个新的“.toolbar”修饰符。工具栏因所使用的设备而异,工具栏修饰符应为设备创建正确类型的工具栏。此外,工具栏会根据视图的显示方式而有所不同 - 即您是导航到场景还是以模态方式呈现场景?
在下面的 playground 代码中,有两个 View 结构。第一个称为 MainToolbarView
并显示(我相信)就好像操场已经导航到它一样。第二个称为 PresentedView
并从 MainToolbarView
.
模态呈现
在 MainToolbarView 中,工具栏有其 Save
和 Cancel
按钮(.navigationBarLeading
和 .navigationBarTrailing
)的位置。这很好用。点击任一按钮都会导致文本字段显示“保存”或“取消”。
当点击 Present Sheet
按钮时,将以模态方式呈现第二个视图。显示的 sheet 的工具栏中存在问题。工具栏为其 Confirm
和 Deny
按钮(.confirmationAction
和 .cancellationAction
)使用语义放置。但是,仅显示 Confirm
按钮。
谁能告诉我为什么 MainToolbarView
上显示了两个按钮,而 PresentedView
工具栏上只有一个按钮?我试过更改按钮的顺序,将两个按钮变成一个 HStack,甚至尝试使用位置放置。 None 这些选项对我有用。
import SwiftUI
import PlaygroundSupport
struct MainToolbarView: View {
@State private var buttonIdentifier = "initial state"
@State private var showSheet = false
var body: some View {
NavigationView {
VStack {
Spacer()
Text( $buttonIdentifier.wrappedValue )
Spacer()
Button( "Present Sheet" )
{ showSheet = true }
Spacer()
}
.toolbar {
ToolbarItem( placement: .navigationBarLeading )
{ Button( "Save", action: reportSave ) }
ToolbarItem( placement: .navigationBarTrailing )
{ Button( "Cancel", action: reportCancel ) }
}
.navigationBarTitle( "MAIN" )
}
.sheet(isPresented: $showSheet )
{ PresentedView(buttonIdentifier: $buttonIdentifier ) }
}
private func reportSave()
{
buttonIdentifier = "save"
}
private func reportCancel()
{
buttonIdentifier = "cancel"
}
}
struct PresentedView: View {
// MARK: API
@Binding var buttonIdentifier: String
// MARK: instance variables
@Environment( \.presentationMode ) var mode
//.confirmationAction
var body: some View {
NavigationView {
Text( "Tap action buttons" )
.toolbar {
ToolbarItem( placement: .confirmationAction )
{ Button( "Confirm", action: reportConfirm ) }
ToolbarItem( placement: .cancellationAction )
{ Button( "Deny", action: reportDenied ) }
}
.navigationBarTitle( "SHEET" )
}
}
private func reportDenied() {
buttonIdentifier = "sheet denied"
self.mode.wrappedValue.dismiss()
}
private func reportConfirm() {
buttonIdentifier = "sheet confirmed"
self.mode.wrappedValue.dismiss()
}
}
PlaygroundPage.current.setLiveView( MainToolbarView() )
`
我认为诀窍(对我来说是一个错误)是使用 .navigationBarBackButtonHidden(true) 修饰符。使用它后(将其添加到 .navigationBarTitle( "SHEET" ) 下方),我看到了两个按钮。
WWDC 2020 SwiftUI 演讲提到了一个新的“.toolbar”修饰符。工具栏因所使用的设备而异,工具栏修饰符应为设备创建正确类型的工具栏。此外,工具栏会根据视图的显示方式而有所不同 - 即您是导航到场景还是以模态方式呈现场景?
在下面的 playground 代码中,有两个 View 结构。第一个称为 MainToolbarView
并显示(我相信)就好像操场已经导航到它一样。第二个称为 PresentedView
并从 MainToolbarView
.
在 MainToolbarView 中,工具栏有其 Save
和 Cancel
按钮(.navigationBarLeading
和 .navigationBarTrailing
)的位置。这很好用。点击任一按钮都会导致文本字段显示“保存”或“取消”。
当点击 Present Sheet
按钮时,将以模态方式呈现第二个视图。显示的 sheet 的工具栏中存在问题。工具栏为其 Confirm
和 Deny
按钮(.confirmationAction
和 .cancellationAction
)使用语义放置。但是,仅显示 Confirm
按钮。
谁能告诉我为什么 MainToolbarView
上显示了两个按钮,而 PresentedView
工具栏上只有一个按钮?我试过更改按钮的顺序,将两个按钮变成一个 HStack,甚至尝试使用位置放置。 None 这些选项对我有用。
import SwiftUI
import PlaygroundSupport
struct MainToolbarView: View {
@State private var buttonIdentifier = "initial state"
@State private var showSheet = false
var body: some View {
NavigationView {
VStack {
Spacer()
Text( $buttonIdentifier.wrappedValue )
Spacer()
Button( "Present Sheet" )
{ showSheet = true }
Spacer()
}
.toolbar {
ToolbarItem( placement: .navigationBarLeading )
{ Button( "Save", action: reportSave ) }
ToolbarItem( placement: .navigationBarTrailing )
{ Button( "Cancel", action: reportCancel ) }
}
.navigationBarTitle( "MAIN" )
}
.sheet(isPresented: $showSheet )
{ PresentedView(buttonIdentifier: $buttonIdentifier ) }
}
private func reportSave()
{
buttonIdentifier = "save"
}
private func reportCancel()
{
buttonIdentifier = "cancel"
}
}
struct PresentedView: View {
// MARK: API
@Binding var buttonIdentifier: String
// MARK: instance variables
@Environment( \.presentationMode ) var mode
//.confirmationAction
var body: some View {
NavigationView {
Text( "Tap action buttons" )
.toolbar {
ToolbarItem( placement: .confirmationAction )
{ Button( "Confirm", action: reportConfirm ) }
ToolbarItem( placement: .cancellationAction )
{ Button( "Deny", action: reportDenied ) }
}
.navigationBarTitle( "SHEET" )
}
}
private func reportDenied() {
buttonIdentifier = "sheet denied"
self.mode.wrappedValue.dismiss()
}
private func reportConfirm() {
buttonIdentifier = "sheet confirmed"
self.mode.wrappedValue.dismiss()
}
}
PlaygroundPage.current.setLiveView( MainToolbarView() )
`
我认为诀窍(对我来说是一个错误)是使用 .navigationBarBackButtonHidden(true) 修饰符。使用它后(将其添加到 .navigationBarTitle( "SHEET" ) 下方),我看到了两个按钮。