SwiftUI:如何使用语义放置呈现多个 ToolbarItem?

Posted

技术标签:

【中文标题】SwiftUI:如何使用语义放置呈现多个 ToolbarItem?【英文标题】:SwiftUI: how to present more than one ToolbarItem using semantic placement? 【发布时间】:2020-07-17 18:46:09 【问题描述】:

WWDC 2020 SwiftUI 演讲提到了一个新的“.toolbar”修饰符。工具栏因使用的设备而异,工具栏修饰符应为设备创建正确类型的工具栏。此外,工具栏会根据视图的显示方式而有所不同 - 即您是导航到场景还是以模态方式呈现场景?

在下面的操场代码中,有两个 View 结构。第一个被称为MainToolbarView 并被显示(我相信)就好像操场已经导航到它一样。第二个称为PresentedView,从MainToolbarView 模态呈现。

在 MainToolbarView 中,工具栏有其SaveCancel 按钮(.navigationBarLeading.navigationBarTrailing)的位置。这工作正常。点击任一按钮都会导致文本字段显示“保存”或“取消”。

当点击Present Sheet 按钮时,第二个视图以模态方式呈现。显示的工作表的工具栏中存在问题。工具栏对其ConfirmDeny 按钮(.confirmationAction.cancellationAction)使用语义放置。但是,只显示Confirm 按钮。

谁能告诉我为什么MainToolbarView 上显示了两个按钮,而PresentedView 工具栏上只有一个按钮?我尝试过更改按钮的顺序,将两个按钮变成一个 HStack,甚至尝试使用位置放置。这些选项都不适合我。

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() )

`

【问题讨论】:

我想这是 Playground 错误。在实际项目中按预期工作。使用 Xcode 12 / ios 14 测试。 我得到了不同的结果,只显示了确认按钮,而不是确认和拒绝按钮。模拟器指示它运行 iOS 14.0。 Xcode 的版本为 12.0 beta 2 (12A6163b)。您是否有机会使用真实设备?感谢您的回复! 【参考方案1】:

我认为诀窍(对我来说是一个错误)是使用 .navigationBarBackButtonHidden(true) 修饰符。使用后(将其添加到 .navigationBarTitle("SHEET") 下方),我看到了两个按钮。

【讨论】:

谢谢你,Jarnaez 太好了,这是一个 SwiftUI 错误

以上是关于SwiftUI:如何使用语义放置呈现多个 ToolbarItem?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

如何使用 SwiftUI 呈现警报

如何使用 UIViewControllerRepresentable 在 SwiftUI 中呈现 UICollectionView

如何使用 SwiftUI 连续呈现两个警报视图

如何在 SwiftUI 中呈现全屏 AVPlayerViewController

如何在 SwiftUI 中动态推送视图或呈现视图?