ios - SwiftUI 中具有可变数量选项卡的自定义选项卡栏

标签 ios swift swiftui swiftui-tabview

我正在尝试在 iPad 版 Safari 中复制标签栏,如下所示:

enter image description here

(是否有第三方库可以做到这一点?我找不到)

我正在使用下面的代码。结果是这样的:

enter image description here

我想我需要以某种方式将 View 转换为数组,并有一个按钮(在选项卡或页面上)来添加和删除选项卡。知道怎么做吗?

import SwiftUI

struct TabLabel : View {

      var text : String
      var imageName : String
      var color : Color

      var body : some View {
            VStack() {
                  Image(systemName: imageName)
                  Text(text).font(.caption)
            }.foregroundColor(color)
      }
}

struct TabButton : View {
      @Binding var currentSelection : Int
      var selectionIndex : Int
      var label : TabLabel

      var body : some View {
            Button(action: { self.currentSelection = self.selectionIndex }) { label }.opacity(selectionIndex == currentSelection ? 0.5 : 1.0)
      }
}

struct CustomTabBarView<SomeView1 : View, SomeView2 : View, SomeView3 : View> : View {


      var view1 : SomeView1
      var view2 : SomeView2
      var view3 : SomeView3

      @State var currentSelection : Int = 1
      var body : some View {

            let label1 = TabLabel(text: "First", imageName:  "1.square.fill", color: Color.red)
            let label2 = TabLabel(text: "Second", imageName:  "2.square.fill", color: Color.purple)
            let label3 = TabLabel(text: "Third", imageName:  "3.square.fill", color: Color.blue)

            let button1 = TabButton(currentSelection: $currentSelection, selectionIndex: 1, label: label1)
            let button2 = TabButton(currentSelection: $currentSelection, selectionIndex: 2, label: label2)
            let button3 = TabButton(currentSelection: $currentSelection, selectionIndex: 3, label: label3)


            return VStack() {
                
                HStack() {
                      button1
                      Spacer()
                      button2
                      Spacer()
                      button3

                }.padding(.horizontal, 48)
                      .frame(height: 48.0)
                      .background(Color(UIColor.systemGroupedBackground))
                
                  Spacer()

                  if currentSelection == 1 {
                        view1
                  }
                  else if currentSelection == 2 {
                        view2
                  }
                  else if currentSelection == 3 {
                        view3
                  }

                  Spacer()

                  
            }

      }
}



struct ContentView: View {
    @State private var showGreeting = true
    var body: some View {
        
                let view1 = VStack() {
                      Text("The First Tab").font(.headline)
                      Image(systemName: "triangle").resizable().aspectRatio(contentMode: .fit).frame(width: 100)
                }

                let view2 = Text("Another Tab").font(.headline)
                let view3 = Text("The Final Tab").font(.headline)

                return CustomTabBarView(view1: view1, view2: view2, view3: view3)
          }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

最佳答案

与 SwiftUI 的许多问题一样,这似乎过于复杂,因为您将 state 的概念与该状态在屏幕上的绘制方式混合在一起。

暂时去掉视觉效果,你所拥有的数据是:

  • 一个有序的页面集合,每个页面都有一个标题和图片
  • 该集合中哪个页面处于事件状态的概念

(请注意,我在这里称它们为“页面”是为了尝试将它们与作为选项卡的视觉表示分开。)

您还有一些会改变该数据的操作:

  • 您的用户可以选择哪个页面应该是事件页面
  • 他们可以将新页面添加到集合中
  • 他们可以从集合中删除现有页面

现在,如果您将这些小步骤视为您的数据模型,您可以构建一个或多个对象来干净地封装它。

然后,您可以继续确定 SwiftUI 如何表示该数据以及它如何包含 Action 触发器。例如:

  • 一个水平标签列表循环遍历有序的页面集合并呈现每个页面
  • 每个选项卡都有一个按钮操作,当点击该按钮时,该按钮将设置为事件按钮
  • 每个选项卡都有一个关闭按钮,点击该按钮会将其从页面集合中移除
  • 点击单独的按钮可以将新页面添加到集合中

等等。希望您能看到 SwiftUI 中的每个 View 现在都有特定的用途,并且应该更容易让您思考。

您甚至可以决定使用不同的 UI – 例如,您可以在 List 中或在 iPhone 的 Safari 页面 View 之类的网格中垂直列出您的页面。但即使你这样做了,你的基础数据也不会改变。

关于ios - SwiftUI 中具有可变数量选项卡的自定义选项卡栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70741860/

相关文章:

ios - 在swift中,当一个属性没有默认值时,其他属性持有的默认值就没有用了?

swiftui - 如何在 SwiftUI 中交换 TabView 项目?

SwiftUI - 对重新加载 View 的状态变量进行动画处理会导致其短暂淡出并返回

ios - 'friend' 在 Obj c 中做什么?

ios - Objective-C - 模态内的旋转甚至 shouldAutoRotate = false

swift - 为什么在添加单个文档时 firestore 监听器返回 .added 两次?

ios - 应用暂停时是否可以启动上传?

swift - 在 WatchOS 上的 SwiftUI 应用程序中是否可以进行基于页面的导航?

ios - AVSpeechSynthesizer 代表不在 iOS 11 中调用

iPhone 内存管理 : a release after setting self. someProperty = nil