我有一个分段控件,有两个分段,如图所示。我想让用户通过向右或向左滑动在两个片段之间切换,并相应地显示相应的视图。我查阅了几篇文章,但没有找到实现此功能的解决方案。
我使用按钮来实现此功能,但我不确定如何启用滑动功能。
struct ScheduleView: View {
// MARK: - Variables
@State private var playerName: String = ""
@State private var pastShown: Bool = false
@State private var presentAlert: Bool = false
@State private var goToGroupChat: Bool = false
private var items = ["Upcoming", "Past"]
var body: some View {
NavigationView {
ZStack {
VStack {
HStack {
VStack(alignment: .leading) {
Text("Hello!,")
.robotoRegularFont(size: 14)
.foregroundColor(Color.custom64B054Color)
Text("John Andrew")
.robotoRegularFont(size: 14)
.foregroundColor(Color.custom333333Color)
}
Spacer()
Image("appIcon_icon")
.resizable()
.frame(width: 32, height: 32)
}
.padding(.top, 24)
// MARK: - Upcoming and Past Views
VStack(spacing: 8) {
HStack(alignment: .center, spacing: 0) {
Spacer()
// MARK: - Button Upcoming
ZStack {
Button {
print("Upcoming action")
self.pastShown = false
} label: {
Text("Upcoming")
.font(.custom(self.pastShown ? "Roboto-Light" : "Roboto-Medium", size: 15))
.foregroundColor(self.pastShown ? .black.opacity(0.7) : .black)
}
}
.frame(width: UIScreen.main.bounds.width / 2 - 18)
Spacer()
Spacer()
// MARK: - Button Past
ZStack {
Button {
print("Past action")
self.pastShown = true
} label: {
Text("Past")
.font(.custom(self.pastShown ? "Roboto-Medium" : "Roboto-Light", size: 15))
.foregroundColor(self.pastShown ? .black : .black.opacity(0.7))
}
}
.frame(width: UIScreen.main.bounds.width / 2 - 18)
Spacer()
}
let upcoming = Capsule()
.fill(Color.black.opacity(self.pastShown ? 0.2 : 1))
.frame(maxWidth: .infinity, maxHeight: 1.5)
let past = Capsule()
.fill(Color.black.opacity(self.pastShown ? 1 : 0.2))
.frame(maxWidth: .infinity, maxHeight: 1.5)
HStack(alignment: .center, spacing: 0) {
upcoming
past
}
}
.padding(.top, 8)
.padding(.horizontal, -18)
ScrollView(.vertical, showsIndicators: false) {
// MARK: - Past View
if self.pastShown {
Text("past")
} else {
// MARK: - Upcoming View
LazyVStack(spacing: 20) {
MatchInfoCell(playerType: "Doubles", skillRange: "minimum", noOfParticipants: "2/4", date: "Tues, Oct 25", time: "04:00 PM", court: "Tour Greens Houston Serves The Houston Area", isForSchedule: true, lookingButtonAction: {
print("lookingButtonAction")
}, gameOnButtonAction: {
print("gameOnButtonAction")
}, noGameButtonAction: {
print("noGameButtonAction")
}, messageButtonAction: {
print("messageButtonAction")
self.goToGroupChat.toggle()
}, addGuestButtonAction: {
print("addGuestButtonAction")
withAnimation {
self.presentAlert.toggle()
}
})
}
}
}
.padding(.top)
.background(Color.clear)
}
.padding(.horizontal, 18)
// MARK: - Custom Alert for Add Guest
if self.presentAlert {
VStack {
CustomAlertView(alertTitle: "Are you sure you want to add a Guest in this match?", nonFilledButtonTitle: "No", filledButtonTitle: "Yes", nonFilledButtonAction: {
withAnimation {
self.presentAlert.toggle()
}
}, filledButtonAction: {
withAnimation {
self.presentAlert.toggle()
}
}, presentAlert: $presentAlert)
}
}
// MARK: - Navigate to Group Chat
NavigationLink("", destination: GroupChatView().navigationBarHidden(true).navigationBarBackButtonHidden(true), isActive: $goToGroupChat)
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
}
如果有人可以为我提供如何实现这一目标的指导,我将不胜感激!
谢谢您!
因此,为了使其正常工作,我几乎使用了您的所有代码。 重要的部分是手势修改器:
.gesture(
DragGesture()
.onChanged({ value in
let translationX = value.translation.width
let velocity = abs(value.velocity.width)
let predictedEnd = value.predictedEndTranslation.width
print("Entered \(translationX), velocity \(velocity)")
if (translationX > 200 || predictedEnd > 200) && velocity > 500 {
withAnimation(.smooth) {
self.pastShown = false
}
} else if (translationX < -200 || predictedEnd > -200) && velocity > 500 {
withAnimation(.smooth) {
self.pastShown = true
}
}
})
)
根据需要尝试并调整这些值。 您可以将其添加到 ZStack 的末尾,其中嵌入了您的两个视图(即将到来的和过去的)。另外,您需要将此行添加到包含“过去”选项卡的 ScrollView 中:
.frame(maxWidth: .infinity, maxHeight: .infinity)
使它看起来像这样:
ScrollView(.vertical, showsIndicators: false) {
// MARK: - Past View
if self.pastShown {
Text("past")
} else {
// MARK: - Upcoming View
LazyVStack(spacing: 20) {
// Your code here
}
}
}
.padding(.top)
.background(Color.clear)
.frame(maxWidth: .infinity, maxHeight: .infinity) // <-- The new line
否则,拖动手势只会在屏幕上非常窄的条带上被检测到,从而导致滑动无法正常工作。
让我知道它是否适合您
注意:我使用了红色背景,以便您更好地看到可滑动区域。