在一个小的SwiftUI示例应用程序中,我有一个设置视图,该视图显示了几个选项选择,实现为分段控件。当显示或关闭警报时,这些分段控件中的文本会明显移动。有办法摆脱这种故障吗?
在操场上粘贴以复制:
import SwiftUI
import PlaygroundSupport
struct FlickeringSegmentsView: View {
@State var option = 0
@State var alerting = false
var body: some View {
VStack(alignment: .center, spacing: 120) {
Picker("options", selection: $option) {
Text("Option A").tag(0)
Text("Option B").tag(1)
}
.pickerStyle(SegmentedPickerStyle())
.padding(16)
Button(action: { self.alerting.toggle() },
label: { Text("Show Alert") }
)
.alert(isPresented: $alerting) {
Alert(title: Text("Alert"))
}
}
}
}
PlaygroundPage.current.setLiveView(FlickeringSegmentsView())
我希望下面的代码能为您提供帮助:
public protocol SegmentedPickerViewElementTraits: Hashable {
var localizedText: String { get }
}
public struct SegmentedPickerView<Value, Data, ID, Label>: View
where
Value: SegmentedPickerViewElementTraits,
Data: RandomAccessCollection,
Data.Element == Value,
ID: Hashable,
Label: View {
public let data: Data
public let id: KeyPath<Data.Element, ID>
public let selection: Binding<Value>
public let label: Label
public init(data: Data,
id: KeyPath<Data.Element, ID>,
selection: Binding<Value>,
label: Label) {
self.data = data
self.id = id
self.selection = selection
self.label = label
}
public var body: some View {
Picker(selection: selection, label: label) {
ForEach(data, id: id) {
Text($0.localizedText).tag($0)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
并让我们修改您的代码:
enum Options: UInt8, CaseIterable {
case optionA
case optionB
}
extension Options: SegmentedPickerViewElementTraits {
var localizedText: String {
switch self {
case .optionA:
return "Option A"
case .optionB:
return "Option B"
}
}
}
struct FlickeringSegmentsView: View {
@State
var option: Options = .optionA
@State
var alerting = false
var body: some View {
VStack(alignment: .center, spacing: 120) {
SegmentedPickerView(
data: Options.allCases,
id: \.self,
selection: $option,
label: Text("options")
)
.padding(16)
Button(
action: { self.alerting.toggle() },
label: { Text("Show Alert") }
)
.alert(isPresented: $alerting) {
Alert(title: Text("Alert"))
}
}
}
}