导航栏项目自动移动 SwiftUI

Posted

技术标签:

【中文标题】导航栏项目自动移动 SwiftUI【英文标题】:Navigation Bar Item Move Automatically SwiftUI 【发布时间】:2021-03-19 06:43:23 【问题描述】:

我试图在右侧显示一个导航栏项目,我几乎成功了,但我在最后一刻卡住了我的导航右键在显示另一个视图后自动移动。请检查下面给出的我的代码和屏幕截图。


struct NvaigationButton: View 
    @State private var showPopUpFlgInapp = false
    var body: some View 
        NavigationView 
            ZStack 
                ScrollView 
                    VStack 
                        Image("DemoImage1")
                            .resizable()
                            .aspectRatio(16/9, contentMode: .fit)
                    
                    Spacer()
                
            
            .navigationBarTitle("", displayMode: .inline)
         .edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading:
                                    Button(action: 
                                    ) 
                                        HStack 
                                            Image( "BackButtonWithColor")
                                        ,trailing:  AnyView(self.trailingButton))
        
    
    
    var trailingButton: some View 
        HStack 
            if showPopUpFlgInapp != true 
                Button(action: 
                    showPopUpFlgInapp = true
                ) 
                    HStack 
                        Image("ThreeDotsWithBckground")
                    
                
                
            else if showPopUpFlgInapp == true 
                showFlagInAppr(showPopUpFlgInapp:$showPopUpFlgInapp,action: 
                    showPopUpFlgInapp = false
                )
            
        
    


struct showFlagInAppr: View 
    @Binding var showPopUpFlgInapp: Bool
    var action: () -> Void
    var body: some View 
        if showPopUpFlgInapp 
            ZStack 
                VStack(alignment:.leading,spacing:30) 
                    Button(action: action, label: 
                        Text("Flag as inappropriate")
                    )
                
            .padding(20)
            .background(Color.init(UIColor.init(displayP3Red: 29/255, green: 33/255, blue: 33/255, alpha: 1.0)))
            .foregroundColor(.white)
            .cornerRadius(10)
        
    

【问题讨论】:

这肯定是一个错误,你的代码没有问题。 【参考方案1】:

一种可能的解决方案是使用toolbar 而不是navigationBarItems

struct NvaigationButton: View 
    @State private var showPopUpFlgInapp = false
    var body: some View 
        NavigationView 
            ZStack 
                ScrollView 
                    VStack 
                        Image("DemoImage1")
                            .resizable()
                            .aspectRatio(16 / 9, contentMode: .fit)
                    
                    Spacer()
                
            
            .navigationBarTitle("", displayMode: .inline)
            .edgesIgnoringSafeArea(.all)
            .navigationBarBackButtonHidden(true)
            .toolbar  // <- add here
                ToolbarItem(placement: .navigationBarLeading) 
                    Button(action: ) 
                        HStack 
                            Image("BackButtonWithColor")
                        
                    
                
                ToolbarItem(placement: .navigationBarTrailing) 
                    trailingButton
                
            
        
    

    var trailingButton: some View 
        HStack 
            if showPopUpFlgInapp != true 
                Button(action: 
                    showPopUpFlgInapp = true
                ) 
                    HStack 
                        Image("ThreeDotsWithBckground")
                    
                

             else if showPopUpFlgInapp == true 
                Text("") // this prevents `showFlagInAppr` from showing inline
                showFlagInAppr(showPopUpFlgInapp: $showPopUpFlgInapp, action: 
                    showPopUpFlgInapp = false
                )
            
        
    

注意:对于toolbar 的当前行为,我们需要添加一个额外的空文本,如this answer 以防止showFlagInAppr 显示内联。

【讨论】:

【参考方案2】:

由于您的问题是(Xcode 版本 12.4 (12D4e))中的一个错误,我们对此无能为力,因此我在此处提供了一种自定义方法来解决此问题:



import SwiftUI

struct ContentView: View 
    var body: some View 

        NvaigationButton()
        
    


struct NvaigationButton: View 
    
    @State private var showPopUpFlgInapp = false
    
    var body: some View 
        
        NavigationView 
            
            ZStack 
                
                Text("Hello World!")
                
            
            .navigationBarTitle("", displayMode: .inline)
            .edgesIgnoringSafeArea(.all)
            .navigationBarBackButtonHidden(true)
   
        
        .trailingNavigationBarItems  trailingButton.padding()        // <<: Apply Here!
        
    
    
    

    var trailingButton: some View 
        HStack 
            if showPopUpFlgInapp != true 
                Button(action: 
                    showPopUpFlgInapp = true
                ) 
                    HStack 
                        Image(systemName: "star")
                    
                
                
            else if showPopUpFlgInapp == true 
                showFlagInAppr(showPopUpFlgInapp:$showPopUpFlgInapp,action: 
                    showPopUpFlgInapp = false
                )
            
        
 
    


struct showFlagInAppr: View 
    @Binding var showPopUpFlgInapp: Bool
    var action: () -> Void
    var body: some View 
        if showPopUpFlgInapp 
            ZStack 
                VStack(alignment:.leading,spacing:30) 
                    Button(action: action, label: 
                        Text("Flag as inappropriate")
                    )
                
            
            .padding(20)
            .background(Color.init(UIColor.init(displayP3Red: 29/255, green: 33/255, blue: 33/255, alpha: 1.0)))
            .foregroundColor(.white)
            .cornerRadius(10)
        
    


struct TrailingNavigationBarItems<InputContent: View>: ViewModifier 

    var inputContent: () -> InputContent

    func body(content: Content) -> some View 

        return content
            .overlay(inputContent(), alignment: .topTrailing)

    
    



extension View 

    func trailingNavigationBarItems<InputContent: View>(_ inputContent: @escaping () -> InputContent) -> some View 

        return self.modifier(TrailingNavigationBarItems(inputContent: inputContent))

    



【讨论】:

我的 Xcode 版本 12.3 (12C33) 我会检查你的解决方案谢谢你的回复@Punk @ShamDhiman:不客气,因为我注意到这是一个错误并且你的代码很好,我说我们不能等待苹果修复,我试图以我的方式修复它。跨度>

以上是关于导航栏项目自动移动 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中设置导航栏项目样式

向后滑动失败时,SwiftUI 导航栏项目变得混乱

SwiftUI:Slider 在导航栏项目的前导/尾随时的奇怪行为

导航栏中的 SwiftUI 元素不响应状态

更新 SwiftUI 导航栏标题

SwiftUI 和双导航栏