如何在 SwiftUI 中使用多个 Picker 更改 UIPickerView 宽度?

leo*_*oe1 3 uikit ios swift swiftui

我需要使用 UIPickerView 而不是 SwiftUI Picker,因为它存在一些错误,并且我需要对其进行更多控制。

使用下面的方法一切正常,但是,我需要一个宽度较小的选择器(约为原始宽度的 70%),但仍然显示所有三个选择器,并且仍然具有灰色背景的圆角(因此灰色背景框架宽度和三个拾取器之间的间距应减小)。

我尝试修改选择器的框架及其超级视图,但这根本不起作用。在 SwiftUI 中设置框架宽度,然后使用剪裁修饰符切断圆边,并切断数字的某些部分(所以这是不可能的)。

有人知道该怎么做吗?多谢!

在此输入图像描述

import SwiftUI

struct ContentView: View {

    @State private var selections: [Int] = [5, 10, 50]

    var body: some View {
        MainPicker(pickerSelections: self.$selections)
    }
}

struct MainPicker: View {
    
    @Binding var pickerSelections: [Int]
    
    private let data: [[String]] = [
        Array(0...59).map { "\($0 < 10 ? "0" : "")" + "\($0)" },
        Array(0...59).map { "\($0 < 10 ? "0" : "")" + "\($0)" },
        Array(0...59).map { "\($0 < 10 ? "0" : "")" + "\($0)" }
    ]
    
    var body: some View {
        HStack{
            PickerView(data: data, selections: self.$pickerSelections)
        }
    }
}

struct PickerView: UIViewRepresentable {
    var data: [[String]]
    @Binding var selections: [Int]

    //makeCoordinator()
    func makeCoordinator() -> PickerView.Coordinator {
        Coordinator(self)
    }

    //makeUIView(context:)
    func makeUIView(context: UIViewRepresentableContext<PickerView>) -> UIPickerView {

        let hoursLabel = UILabel()
        let minLabel = UILabel()
        let secLabel = UILabel()
        hoursLabel.text = "h"
        minLabel.text = "m"
        secLabel.text = "s"
        
        let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) //doesnt work
        
        
        picker.dataSource = context.coordinator
        picker.delegate = context.coordinator
        
        picker.superview?.frame = CGRect(x: 0, y: 0, width: 100, height: 100) //doesnt work
        
        return picker
    }

    //updateUIView(_:context:)
    func updateUIView(_ view: UIPickerView, context: UIViewRepresentableContext<PickerView>) {
        for i in 0...(self.selections.count - 1) {
            if(context.coordinator.initialSelection[i] != self.selections[i]){
                view.selectRow(self.selections[i], inComponent: i, animated: false)
                context.coordinator.initialSelection[i] = self.selections[i]
            }
        }
    }

    class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
        var parent: PickerView
        var initialSelection = [-1, -1, -1]
        
        //init(_:)
        init(_ pickerView: PickerView) {
            
            self.parent = pickerView
        }

        //numberOfComponents(in:)
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return self.parent.data.count
        }

        //pickerView(_:numberOfRowsInComponent:)
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return self.parent.data[component].count
        }
        
        func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return 50
        }

        //pickerView(_:titleForRow:forComponent:)
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return self.parent.data[component][row]
        }

        //pickerView(_:didSelectRow:inComponent:)
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            self.parent.selections[component] = row
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 5

您需要删除压缩阻力优先级

let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
Run Code Online (Sandbox Code Playgroud)

然后可以根据需要在 SwiftUI 部分使用任何框架(静态或计算)

演示

    MainPicker(pickerSelections: self.$selections)
        .frame(width: 200)
Run Code Online (Sandbox Code Playgroud)

使用 Xcode 11.7 / iOS 13.7 准备和测试演示