SwiftUI 可重用视图
SwiftUI reusable view
我有一个视图“TopTabBar”,我在两个不同的屏幕上使用它。但在一个屏幕上应该有 2 个按钮,而在另一个屏幕上应该有 4 个。
在通常的 swift 中,我会在这个 TopTabBar 中创建一个函数,我会用它向 Stack 添加按钮,并从我使用它的地方创建它们。但在 SwiftUI 中我不能那样做。
我怎样才能重新使用屏幕并从外部填充适量的按钮?
import SwiftUI
struct TopBar: View {
var firstViewTitle: String
var secondViewTitle: String
var thirdViewTitle: String?
var fourthViewTitle: String?
@Binding var tabIndex: Int
var body: some View {
HStack(spacing: 0) {
TabBarButton(text: firstViewTitle, isSelected: .constant(tabIndex == 0))
.onTapGesture { onButtonTapped(index: 0) }
TabBarButton(text: secondViewTitle, isSelected: .constant(tabIndex == 1))
.onTapGesture { onButtonTapped(index: 1) }
TabBarButton(text: thirdViewTitle ?? "", isSelected: .constant(tabIndex == 2))
.onTapGesture { onButtonTapped(index: 2) }
TabBarButton(text: fourthViewTitle ?? "", isSelected: .constant(tabIndex == 3))
.onTapGesture { onButtonTapped(index: 3) }
}
.border(width: 1, edges: [.bottom], color: .lightGrey)
.frame(width: UIScreen.screenWidth, height: 50, alignment: .center)
}
private func onButtonTapped(index: Int) {
withAnimation { tabIndex = index }
}
}
struct TabBarButton: View {
let text: String
@Binding var isSelected: Bool
var body: some View {
Text(text)
.foregroundColor(isSelected ? .black : .gray)
.fontWeight(isSelected ? .heavy : .regular)
.padding(.bottom, 10)
.border(width: isSelected ? 2 : 0, edges: [.bottom], color: .black)
.frame(width: UIScreen.screenWidth/4, height: 50, alignment: .center)
.background(Color.random)
}
}
struct Usable: View {
@State var tabIndex = 0
var body: some View {
NavigationView {
ZStack {
if tabIndex == 1 {
debugPring("xxx")
}
VStack {
TopBar(firstViewTitle: "first", secondViewTitle: "second", thirdViewTitle: "third", fourthViewTitle: "fourth" ,tabIndex: $tabIndex).padding(.top, 20)
if tabIndex == 0 {
debugPrint("xxx")
}
Spacer()
}
}
.navigationBarHidden(true)
}.accentColor(Color.black)
}
}
实际上有很多选项,但根据您当前的设计,可以只将它们设为有条件的,例如
HStack(spacing: 0) {
TabBarButton(text: firstViewTitle, isSelected: .constant(tabIndex == 0))
.onTapGesture { onButtonTapped(index: 0) }
TabBarButton(text: secondViewTitle, isSelected: .constant(tabIndex == 1))
.onTapGesture { onButtonTapped(index: 1) }
if let title = thirdViewTitle {
TabBarButton(text: title, isSelected: .constant(tabIndex == 2))
.onTapGesture { onButtonTapped(index: 2) }
}
if let title = fourthViewTitle {
TabBarButton(text: title, isSelected: .constant(tabIndex == 3))
.onTapGesture { onButtonTapped(index: 3) }
}
}
我有一个视图“TopTabBar”,我在两个不同的屏幕上使用它。但在一个屏幕上应该有 2 个按钮,而在另一个屏幕上应该有 4 个。 在通常的 swift 中,我会在这个 TopTabBar 中创建一个函数,我会用它向 Stack 添加按钮,并从我使用它的地方创建它们。但在 SwiftUI 中我不能那样做。 我怎样才能重新使用屏幕并从外部填充适量的按钮?
import SwiftUI
struct TopBar: View {
var firstViewTitle: String
var secondViewTitle: String
var thirdViewTitle: String?
var fourthViewTitle: String?
@Binding var tabIndex: Int
var body: some View {
HStack(spacing: 0) {
TabBarButton(text: firstViewTitle, isSelected: .constant(tabIndex == 0))
.onTapGesture { onButtonTapped(index: 0) }
TabBarButton(text: secondViewTitle, isSelected: .constant(tabIndex == 1))
.onTapGesture { onButtonTapped(index: 1) }
TabBarButton(text: thirdViewTitle ?? "", isSelected: .constant(tabIndex == 2))
.onTapGesture { onButtonTapped(index: 2) }
TabBarButton(text: fourthViewTitle ?? "", isSelected: .constant(tabIndex == 3))
.onTapGesture { onButtonTapped(index: 3) }
}
.border(width: 1, edges: [.bottom], color: .lightGrey)
.frame(width: UIScreen.screenWidth, height: 50, alignment: .center)
}
private func onButtonTapped(index: Int) {
withAnimation { tabIndex = index }
}
}
struct TabBarButton: View {
let text: String
@Binding var isSelected: Bool
var body: some View {
Text(text)
.foregroundColor(isSelected ? .black : .gray)
.fontWeight(isSelected ? .heavy : .regular)
.padding(.bottom, 10)
.border(width: isSelected ? 2 : 0, edges: [.bottom], color: .black)
.frame(width: UIScreen.screenWidth/4, height: 50, alignment: .center)
.background(Color.random)
}
}
struct Usable: View {
@State var tabIndex = 0
var body: some View {
NavigationView {
ZStack {
if tabIndex == 1 {
debugPring("xxx")
}
VStack {
TopBar(firstViewTitle: "first", secondViewTitle: "second", thirdViewTitle: "third", fourthViewTitle: "fourth" ,tabIndex: $tabIndex).padding(.top, 20)
if tabIndex == 0 {
debugPrint("xxx")
}
Spacer()
}
}
.navigationBarHidden(true)
}.accentColor(Color.black)
}
}
实际上有很多选项,但根据您当前的设计,可以只将它们设为有条件的,例如
HStack(spacing: 0) {
TabBarButton(text: firstViewTitle, isSelected: .constant(tabIndex == 0))
.onTapGesture { onButtonTapped(index: 0) }
TabBarButton(text: secondViewTitle, isSelected: .constant(tabIndex == 1))
.onTapGesture { onButtonTapped(index: 1) }
if let title = thirdViewTitle {
TabBarButton(text: title, isSelected: .constant(tabIndex == 2))
.onTapGesture { onButtonTapped(index: 2) }
}
if let title = fourthViewTitle {
TabBarButton(text: title, isSelected: .constant(tabIndex == 3))
.onTapGesture { onButtonTapped(index: 3) }
}
}