Test

BetterPicker

SwiftUI Picker 的替代方案,支持自定义样式。

基本用法

struct Item: Identifiable {
    let id: Int

    init(id: Int) {
        self.id = id
    }
}

struct ItemLabel: View {
    private let itemId: String

    init(item: Item) {
        self.itemId = item.id
    }

    var body: some View {
        Text("Cell - \(itemId)")
    }
}

struct ItemPicker: View {
    private let items: [Item] = 0..<100
    @State private var selection: Item.ID = 0

    var body: some View {
        BetterPicker(items, selection: $selection, content: ItemLabel.init)
    }
}

安装

目前仅支持 Swift Package Manager。通过以下 URL 将其添加为软件包:https://github.com/MFB-Technologies-Inc/swiftui-pick-better.git

git@github.com:MFB-Technologies-Inc/swiftui-pick-better.git

支持的选项类型

Picker 中显示的选项必须符合 Identifiable 协议,因为这是它们与当前选择关联的方式。

支持的选择类型

选择值必须符合 Hashable 协议。其中 T 是给定可选项的选择值,选择可以是:

样式

与 SwiftUI 的 PickerStyle 不同,BetterPicker 支持自定义样式。可以实现 BetterPickerStyle 协议来创建类似于 SwiftUI ButtonStyle 的可重用样式。

BetterPicker 目前包含一种内置样式 PlainInlineBetterPickerStyle,它类似于 iOS 中垂直列表项的默认样式。

StyleBuilder

BetterPicker 包含一个 resultBuilder 类型 StyleBuilder,用于以熟悉的方式有条件地应用样式。

内部原理

AnyView

BetterPicker 确实使用了视图类型擦除,使用了 AnyView。这可能会对包括动画在内的各种事物产生副作用。 但是,到目前为止尚未遇到任何问题。

在没有 ViewModifier 的情况下进行修改

BetterPicker 不通过 ViewModifier 应用样式。 而是使用视图上的实例函数。 因此,样式只能直接应用于 picker 的实例。 这种做法与 SwiftUI 的预期使用方式并不完全一致。 这可能会导致稳定性问题。 但是,到目前为止尚未遇到此类问题。

未来改进

示例

该软件包在 Example 目录中包含一个示例应用程序,具有 iOS,macOS,tvOS 和 watchOS 目标。 此外,该示例还包括一种更复杂的样式 GridBetterPickerStyle