我正在尝试在 iPad 版 Safari 中复制标签栏,如下所示:
(是否有第三方库可以做到这一点?我找不到)
我正在使用下面的代码。结果是这样的:
我想我需要以某种方式将 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/