【问题标题】:SwiftUI: how to get rid of Segmented Control text movement when an alert is shown?SwiftUI:显示警报时如何摆脱分段控制文本移动?
【发布时间】:2020-04-22 01:22:27
【问题描述】:

在一个小型 SwiftUI 应用程序示例中,我有一个设置视图,其中显示了几个选项选择,以分段控件的形式实现。当出现或解除警报时,这些分段控件中的文本会明显移动。有没有办法摆脱这个故障?

将其粘贴到 Playground 中进行复制:

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())

【问题讨论】:

  • 奇怪的事情,但即使我在“选项 A”和“选项 B”之间切换,我也会看到这个故障。在画布和真实设备上测试
  • 是的,选择时会有一个小动作/动画,但我认为这与警报显示时发生的情况不同。另外,为什么警报甚至会对屏幕上的其他任何内容产生影响?我从未见过 UIKit 会发生这种情况。
  • 很遗憾我也遇到了同样的问题,你找到解决办法了吗?
  • 不,很遗憾没有。如果你想欺骗它,我已经提交了反馈 FB7518502。

标签: swiftui uisegmentedcontrol


【解决方案1】:

在 Xcode 12 测试版中使用随附的 iOS 14 模拟器解决了此问题(希望保持这种状态)。

【讨论】:

    【解决方案2】:

    希望下面的代码对你有所帮助:

    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"))
                }
            }
        }
    }
    

    【讨论】:

    • 不,这根本没有帮助。此代码显示的视觉故障与我的完全相同。
    猜你喜欢
    • 1970-01-01
    • 2021-08-11
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多