【SwiftUI】iOS15からWheelPickerStyleが壊れたから自作した

# はじめに
https://qiita.com/SNQ-2001/items/82711dbb3818450c2c1a

iOS15からPickerのwheelがバグが発生しました。
これはOSのバグで現時点では解決方法はないようです。

UIKitを使ってちゃんと使えるWheelPickerを作成します。


# 実装方法
```swift:WheelPickerView
struct WheelPickerView: UIViewRepresentable {

    @Binding private var selection: Int
    private let content: [String]

    init(selection: Binding<Int>, content: [String]) {
        self._selection = selection
        self.content = content
    }

    func makeUIView(context: Context) -> UIPickerView {
        let picker = UIPickerView(frame: .zero)
        picker.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
        picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

        picker.dataSource = context.coordinator
        picker.delegate = context.coordinator

        return picker
    }

    func updateUIView(_ picker: UIPickerView, context: Context) {
        picker.selectRow(selection, inComponent: 0, animated: true)
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
        private var wheelPickerView: WheelPickerView

        init(_ wheelPickerView: WheelPickerView) {
            self.wheelPickerView = wheelPickerView
        }

        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }

        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return wheelPickerView.content.count
        }

        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return wheelPickerView.content[row]
        }
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            wheelPickerView.selection = row
        }
        func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
            let label = (view as? UILabel) ?? UILabel()
            label.text = wheelPickerView.content[row]
            label.textAlignment = .center
            label.adjustsFontSizeToFitWidth = true
            return label
        }
    }
}
```

```swift:ContentView
import SwiftUI

struct ContentView: View {
    @State var selectIndex: Int = 0
    let animals: [String] = ["ライオン", "ニワトリ", "イヌ", "トナカイ", "キツツキ", "モグラ"]
    var body: some View {
        VStack(alignment: .center, spacing: 50) {
            Text("好きな動物は\(animals[selectIndex])です")

            WheelPickerView(selection: $selectIndex, content: animals)
                .frame(width: 200, height: 60)
                .clipped()
        }
    }
}
```
![Simulator Screen Recording - iPhone 12 - 2022-08-25 at 22.22.53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/1d192ded-1509-8944-d5c2-f22d20468247.gif)


# 追記
記事を書いている途中で解決方法を発見しました笑
でも何か副作用があるかもしれないので公式で対応されるまではUIKitで作成したのを使った方がいいかもしれません。

Pickerの高さの+20くらいを設定するとちょうどいい感じになります。
```swift
import SwiftUI

struct ContentView: View {
    @State var selectIndex: Int = 0
    let animals: [String] = ["ライオン", "ニワトリ", "イヌ", "トナカイ", "キツツキ", "モグラ"]
    var body: some View {
        VStack(alignment: .center, spacing: 50) {
            Text("好きな動物は\(animals[selectIndex])です")

            Picker("", selection: $selectIndex) {
                ForEach(0..<animals.count, id: \.self) { index in
                    Text(animals[index])
                }
            }
            .pickerStyle(.wheel)
            .frame(width: 200, height: 60)
        }
    }
}

extension UIPickerView {
    open override var intrinsicContentSize: CGSize {
        return CGSize(width: UIView.noIntrinsicMetric, height: 80)
    }
}
```
![Simulator Screen Recording - iPhone 12 - 2022-08-25 at 22.25.21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4eb7a642-63d9-d251-b7d3-53073a1d61a5.gif)

# 参考記事
https://developer.apple.com/forums/thread/687986