ios - 如何在 SwiftUI 中使用多个 Picker 更改 UIPickerView 的宽度?
问题描述
我需要使用 UIPickerView 而不是 SwiftUI Picker,因为它存在一些错误,我需要对它进行更多控制。
下面的方法一切正常,但是,我需要一个宽度较小的选择器(大约是原始宽度的 70%),但仍然显示所有三个选择器并且仍然具有灰色背景的圆角(所以灰色背景框架宽度和三个拾取器之间的间距应该减小)。
我试图修改选择器的框架及其超级视图,但这根本不起作用。在 SwiftUI 中设置帧宽度,然后使用 clipped 修饰符会切断圆角边缘并切断数字的某些部分(所以这是不可能的)。
有人知道该怎么做吗?非常感谢!
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
}
}
}
解决方案
您需要删除抗压优先级
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
然后可以在 SwiftUI 部分中根据需要使用任何框架(静态或计算)
MainPicker(pickerSelections: self.$selections)
.frame(width: 200)
使用 Xcode 11.7 / iOS 13.7 准备和测试的演示
推荐阅读
- node.js - 客户端和服务器之间的安全密码传输
- node.js - 应用程序部署节点 js,超出实例数量
- ibm-cloud - IBM CIS 是否提供 Cloudfare Workers KV
- audio - 在Ubuntu上使用ffmpeg,如何记录来自音视频USB捕获设备的音视频?
- java - 有界通配符作为方法参数
- angular - 如何使用角度更新列表的项目
- sql - 如何在不加载数据的情况下使用 Spark Scala 创建与 Oracle 的连接?
- c# - 从 XML 数据返回类型 T 的对象
- java - java.io.IOException: toDerInputStream 拒绝标签类型 77
- java - 为什么 CrudRepository.save() 在返回创建的对象时忽略 FetchType.EAGER?