SwiftUI实现点击分段Picker选项后先弹出确认弹窗,确认后再切换选项
How to Add Confirmation Alert Before Segmented Picker Selection Changes in SwiftUI
Got it, let's fix this up! The problem with your current code is that the Picker’s selection is directly bound to favoriteColor—so when you tap a segment, the selection switches immediately, and then the alert pops up. That’s backwards from what you want. Here’s a clean way to implement the "confirm first" behavior:
struct ContentView: View { @State private var favoriteColor = 0 @State private var pendingColorSelection: Int? @State private var showAlert = false var body: some View { VStack { // Use a custom Binding to control when the selection updates Picker("What is your favorite color?", selection: Binding( get: { favoriteColor }, set: { newValue in // Save the tapped value temporarily, then show the alert pendingColorSelection = newValue showAlert = true } )) { Text("Red").tag(0) Text("Green").tag(1) } .pickerStyle(.segmented) .alert("By changing color also modifies other things...change color?", isPresented: $showAlert) { Button("YES") { // Update the actual selection only if user confirms if let newColor = pendingColorSelection { favoriteColor = newColor } } Button("Cancel", role: .cancel) { // Clear the pending value—Picker will revert to the original selection automatically pendingColorSelection = nil } } } } }
How this works:
- Custom Binding: Instead of directly binding to
$favoriteColor, we create a custom binding. Thegetclosure ensures the Picker always displays the current confirmed selection. Thesetclosure triggers when the user taps a new segment—instead of updating the actual selection right away, it saves the new value topendingColorSelectionand shows the alert. - Confirmation Logic:
- If the user taps "YES", we take the pending value and update
favoriteColor, which makes the Picker switch to the new segment. - If the user taps "Cancel", we just clear the pending value. Since the Picker’s binding still reads from
favoriteColor, it stays on the original selection—no extra work needed to revert it.
- If the user taps "YES", we take the pending value and update
- Cancel Role: Adding
role: .cancelto the Cancel button gives it system-standard behavior (like being the default dismiss option, and proper styling on different platforms).
内容的提问来源于stack exchange,提问作者fs_tigre
相关产品推荐
相关产品推荐

