【问题标题】:Is there support for something like TimePicker (Hours, Mins, Secs) in SwiftUI?SwiftUI 中是否支持 TimePicker (Hours, Mins, Secs) 之类的东西?
【发布时间】:2021-06-10 14:12:58
【问题描述】:

我正在尝试实现类似 iOS Timer App 时间选择器控件的功能:

我调查了 DatePicker,但它没有秒视图。

【问题讨论】:

    标签: swift swiftui datepicker timepicker swiftui-layout


    【解决方案1】:

    经过一段时间的调查,发现唯一的解决方案就是从头开始编写它。我在这里为有同样问题的任何人发布它:

    import SwiftUI
    
    struct MultiComponentPicker<Tag: Hashable>: View  {
        let columns: [Column]
        var selections: [Binding<Tag>]
        
        init?(columns: [Column], selections: [Binding<Tag>]) {
            guard !columns.isEmpty && columns.count == selections.count else {
                return nil
            }
            
            self.columns = columns
            self.selections = selections
        }
        
        var body: some View {
            GeometryReader { geometry in
                HStack(spacing: 0) {
                    ForEach(0 ..< columns.count) { index in
                        let column = columns[index]
                        ZStack(alignment: Alignment.init(horizontal: .customCenter, vertical: .center)) {
                            if (!column.label.isEmpty && !column.options.isEmpty) {
                                HStack {
                                    Text(verbatim: column.options.last!.text)
                                        .foregroundColor(.clear)
                                        .alignmentGuide(.customCenter) { $0[HorizontalAlignment.center] }
                                    Text(column.label)
                                }
                            }
                            Picker(column.label, selection: selections[index]) {
                                ForEach(column.options, id: \.tag) { option in
                                    Text(verbatim: option.text).tag(option.tag)
                                }
                            }
                            .pickerStyle(WheelPickerStyle())
                            .frame(width: geometry.size.width / CGFloat(columns.count), height: geometry.size.height)
                            .clipped()
                        }
                        
                    }
                }
            }
        }
    }
    
    extension MultiComponentPicker {
        struct Column {
            struct Option {
                var text: String
                var tag: Tag
            }
            
            var label: String
            var options: [Option]
        }
    }
    
    private extension HorizontalAlignment {
        enum CustomCenter: AlignmentID {
            static func defaultValue(in context: ViewDimensions) -> CGFloat { context[HorizontalAlignment.center] }
        }
        
        static let customCenter = Self(CustomCenter.self)
    }
    
    // MARK: - Demo preview
    struct MultiComponentPicker_Previews: PreviewProvider {
        static var columns = [
            MultiComponentPicker.Column(label: "h", options: Array(0...23).map { MultiComponentPicker.Column.Option(text: "\($0)", tag: $0) }),
            MultiComponentPicker.Column(label: "min", options: Array(0...59).map { MultiComponentPicker.Column.Option(text: "\($0)", tag: $0) }),
            MultiComponentPicker.Column(label: "sec", options: Array(0...59).map { MultiComponentPicker.Column.Option(text: "\($0)", tag: $0) }),
        ]
        
        static var selection1: Int = 23
        static var selection2: Int = 59
        static var selection3: Int = 59
        
        static var previews: some View {
            MultiComponentPicker(columns: columns, selections: [.constant(selection1), .constant(selection2), .constant(selection3)]).frame(height: 300).previewLayout(.sizeThatFits)
        }
    }
    

    下面是它的样子:

    我已经把它变得非常通用,因此您可以将它用于任何类型的多组件选择器,而不仅仅是时间选择器。

    解决方案的基础归功于 Matteo Pacini。

    【讨论】:

    • 您正在使用现有的 Picker!所以你无法摆脱那条带子,仍然不是完美的救赎。
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 2013-08-09
    • 1970-01-01
    • 2022-12-17
    • 2023-03-14
    • 2022-11-01
    • 1970-01-01
    • 2010-10-06
    相关资源
    最近更新 更多