SwiftUI:更改 ZStack .zIndex 顺序

Posted

技术标签:

【中文标题】SwiftUI:更改 ZStack .zIndex 顺序【英文标题】:SwiftUI: change ZStack .zIndex order 【发布时间】:2019-11-27 18:18:01 【问题描述】:

Goal 是一个菜单,其中: 用户点击绿色按钮:显示绿色菜单 用户点击蓝色按钮:显示蓝色菜单

我做了什么: 设置“当点击绿色时,绿色是 ZStack 中的顶层)的状态。

结果: 没用: 当点击绿色时,它变为绿色。但然后我点击蓝色,它保持绿色。逻辑肯定不正确

import SwiftUI

struct Menutest: View 

    @State private var showall = false
    @State private var showgreen = false
    @State private var showyellow = false
    @State private var showblue = false


    var body: some View 


        NavigationView 

           HStack 

            Spacer()

            ZStack 
                Rectangle()
                .foregroundColor(.blue)
                //.opacity(showblue ? 1 : 0)
               .zIndex(showblue ? 1 : 0)

                Rectangle()
                .foregroundColor(.green)
                 //.opacity(showgreen ? 1 : 0)
                .zIndex(showgreen ? 1 : 0)


                Rectangle()
                .foregroundColor(.yellow)
                 //.opacity(showyellow ? 1 : 0)
                .zIndex(showyellow ? 1 : 0)



            
            .frame(width: 400.0)
          //  .offset(x: showall ? 0 : UIScreen.main.bounds.width)
            .animation(.easeInOut)

        





        .navigationBarItems(



            trailing:

            HStack 


            Button(action: 
              //   self.showall.toggle()
                self.showyellow.toggle()
            )
            
            Text("Yellow")

            



           Button(action: 
            //     self.showall.toggle()
            self.showgreen.toggle()
            )
            
            Text("Green")

            


          Button(action: 
               //   self.showall.toggle()
                 self.showblue.toggle()
                )
                
                Text("Blue")


               



             


            )

       
      .navigationViewStyle(StackNavigationViewStyle())



    





struct Menutest_Previews: PreviewProvider 
    static var previews: some View 
        Menutest()
        .colorScheme(.dark)
        .previewDevice("iPad Pro (12.9-inch) (3rd generation)")
    

问题:如何正确设置 Zstack 以显示选定的图层?不必使用 ZIndex,可以是 .hide() 修饰符或其他一些逻辑。

【问题讨论】:

【参考方案1】:

在我看来,如果您有几个 Bool 值,在任何给定时间只有一个值是真的,那么使用枚举来表示选项会更容易 - 管理状态也容易得多。这具有您期望的行为:

struct Menutest: View 

    private enum Selection: String, CaseIterable 
        case blue = "Blue"
        case green = "Green"
        case yellow = "Yellow"

        static let allOptions = Array(Selection.allCases)

        func color() -> Color 
            switch self 
            case .blue:
                return .blue
            case .green:
                return .green
            case .yellow:
                return .yellow
            
        
    

    @State private var showing: Selection? = nil

    var body: some View 
        NavigationView 
            HStack 
                Spacer()
                ZStack 
                    ForEach(Selection.allOptions, id: \.self)  selection in
                        Rectangle()
                            .foregroundColor(selection.color())
                            .zIndex(self.showing == selection ? 1 : 0)
                    
                   .frame(width: 400.0)
                    .animation(.easeInOut)
               .navigationBarItems(trailing:
                HStack 
                    ForEach(Selection.allOptions, id: \.self)  selection in
                        Button(action:  self.showing = selection ) 
                            Text(selection.rawValue)
                        
                    
                )
           .navigationViewStyle(StackNavigationViewStyle())
    

【讨论】:

【参考方案2】:

除了您单击的按钮的 BOOL 之外,您还需要切换其他 BOOL。

以下工作,尽管可能有更优雅的方式来做到这一点。将按钮部分替换为:

Button(action: 
  self.showyellow = true
  self.showgreen = false
  self.showblue = false
 )
 
  Text("Yellow")


Button(action: 
 self.showgreen = true
 self.showblue = false
 self.showyellow = false
)

 Text("Green")


Button(action: 
 self.showblue = true
 self.showyellow = false
 self.showgreen = false
)

 Text("Blue")


在 ZStack 中,元素相互堆叠。第一项是最低层,这些层相互堆叠。

在您的版本中,当您点击黄色时,蓝色和绿色可能仍会堆叠在黄色图层“上方”,因此您需要确保删除其他图层。

【讨论】:

注意原因:这是一个 ZStack。在 ZStack 中,元素相互堆叠。第一项是最低层,这些层相互堆叠。因此,黄色将始终隐藏其他图层。因此,您需要确保在单击其他按钮之一时删除黄色(显示黄色 = false)。希望这有助于解释正在发生的事情。 @dot3,完美配合!非常感谢,祝你有美好的一天

以上是关于SwiftUI:更改 ZStack .zIndex 顺序的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI ZStack 对齐错误

工具栏未正确显示 SwiftUI

在 SwiftUI 中导出文件时显示 ProgressView

List 内的 SwiftUI zIndex

SwiftUI:使用matchedGeometryEffect控制视图上的zIndex

更改状态栏颜色 SwiftUI 没有 UIHosting