问题描述
大家下午好。我希望一个元素的高度调整到最大尺寸。 这是我的代码示例(不起作用):
struct ContentView: View {
private let items: [String] = [
"<|OneLineLongggggggggggggggggggggggggggggggggggggggggg|>","<|TwoLinesLonggggggggggggg\nLongggggggggggggggg|>","<|ThreeLinesLonggggggggggggg\nLongggggggggggggggg\nLongggggggggggggggg|>"
]
@State private var text: String = ""
@State private var index: Int = 0
var body: some View {
BoxCustomPicker(select: self.$text,items: self.items)
}
}
struct BoxCustomPicker : View {
@Binding private var select: String
private let items: [String]
@State private var width: CGFloat = 50
@State private var height: CGFloat = 50
private var selectIndex: Binding<Int> {
.init(
get: {
if let index = self.items.firstIndex(where: { $0 == self.select }) {
return index
}
return 0
},set: {
if self.items.count > $0 {
self.select = self.items[$0]
}
}
)
}
init(select: Binding<String>,items: [String]) {
self._select = select
self.items = items
}
var body: some View {
CustomUIPicker(width: self.$width,height: self.$height,select: self.selectIndex,items: self.items)
.background(
GeometryReader { proxy in
Color.clear
.onAppear {
let width = proxy.size.width
self.width = width
print("width: \(width)")
}
}
)
}
}
struct CustomUIPicker : UIViewRepresentable {
@Binding var width: CGFloat
@Binding var height: CGFloat
@Binding var select: Int
let items: [String]
func makeCoordinator() -> Self.Coordinator {
return Self.Coordinator(self)
}
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIPickerView {
let picker = UIPickerView(frame: .zero)
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
return picker
}
func updateUIView(_ view: UIPickerView,context: UIViewRepresentableContext<Self>) {
print("updateUIView")
}
class Coordinator: NSObject,UIPickerViewDataSource,UIPickerViewDelegate {
var parent: CustomUIPicker
init(_ pickerView: CustomUIPicker) {
self.parent = pickerView
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView,numberOfRowsInComponent component: Int) -> Int {
return parent.items.count
}
func pickerView(_ pickerView: UIPickerView,widthForComponent component: Int) -> CGFloat {
return self.parent.width
}
func pickerView(_ pickerView: UIPickerView,rowHeightForComponent component: Int) -> CGFloat {
print("set heightRow: \(self.parent.height)")
return self.parent.height
}
func pickerView(_ pickerView: UIPickerView,viewForRow row: Int,forComponent component: Int,reusing view: UIView?) -> UIView {
let rowView: RowView = {
if let row = view as? RowView {
row.frame = CGRect(x: 0,y: 0,width: self.parent.width,height: self.parent.height)
return row
}
return .init(frame: CGRect(x: 0,height: self.parent.height))
}()
rowView.setText(self.parent.items[row])
let maxSize: CGSize = .init(width: self.parent.width,height: CGFloat.greatestFiniteMagnitude)
let heightRow = rowView.sizeThatFitsText(maxSize).height
if self.parent.height < heightRow {
dispatchQueue.main.async {
self.parent.height = heightRow
print("update heightRow: \(heightRow)")
pickerView.reloadAllComponents()
}
}
return rowView
}
func pickerView(_ pickerView: UIPickerView,didSelectRow row: Int,inComponent component: Int) {
self.parent.select = row
}
}
}
extension CustomUIPicker.Coordinator {
class RowView : UIView {
private var label: UILabel? = nil {
didSet {
oldValue?.removeFromSuperview()
if let pickerLabel = self.label {
self.addSubview(pickerLabel)
pickerLabel.translatesAutoresizingMaskIntoConstraints = false
let padding: CGFloat = 4
NSLayoutConstraint.activate([
pickerLabel.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor,constant: padding),pickerLabel.trailingAnchor.constraint(equalTo: self.layoutMarginsGuide.trailingAnchor,constant: -padding),pickerLabel.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor,pickerLabel.leadingAnchor.constraint(equalTo: self.layoutMarginsGuide.leadingAnchor,])
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupView()
}
public func setText(_ text: String) {
self.label?.text = text
}
public func sizeThatFitsText(_ size: CGSize) -> CGSize {
return self.label!.sizeThatFits(size)
}
private func setupView() {
let pickerLabel = UILabel(frame: self.bounds)
pickerLabel.text = ""
pickerLabel.adjustsFontSizetoFitWidth = false
pickerLabel.textAlignment = .center
pickerLabel.lineBreakMode = .byCharWrapping
pickerLabel.numberOfLines = 0
self.label = pickerLabel
}
}
}
控制台输出这个日志:
updateUIView
width: 320.0
updateUIView
set heightRow: 50.0
set heightRow: 50.0
update heightRow: 61.0
updateUIView
由于某种原因,更改最大高度后不会请求元素的新高度。 结果是这样的:
最初,我想要一个 Picker 来调整数据并选择元素的最佳高度。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)