如何使 UIPickerView.viewForRow 在中心突出显示,重置行灰色?
Posted
技术标签:
【中文标题】如何使 UIPickerView.viewForRow 在中心突出显示,重置行灰色?【英文标题】:How to make UIPickerView.viewForRow highlighted in the center , the reset row gray? 【发布时间】:2019-11-14 11:38:24 【问题描述】:如何让它更漂亮?
如下图:中间行高亮,其余行灰色。
代码如下:
extension ViewController: UIPickerViewDelegate
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
let info = BeatScalar.generalRates[row]
let general = GeneralRateItem(info.cn, info.ita, info.val)
// gray every row
general.unselected()
decorateView(pickerView, row: row)
return general
// Here is the logic
func decorateView(_ picker: UIPickerView, row: Int)
var frame = picker.frame
frame.origin.y = frame.origin.y + frame.size.height * 0.42
frame.size.height = frame.size.height * 0.16
let mini = max(row-1, 0)
// 19 is total number
let maxi = min(18, row+1)
for i in mini...maxi
if i != row, let item = picker.view(forRow: i, forComponent: 0) as? GeneralRateItem
let f = item.convert(item.frame, to: picker)
if frame.intersects(f) == false
// highlight the center row
item.selected()
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat
return 44
extension ViewController: UIPickerViewDataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int
return 1
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int // 19 is total number
return 19
更多代码在github
我需要使用func pickerView(_ pickerView: UIPickerView, viewForRow
,因为
上面的代码运行良好,缺点是计算量大,并且用一些数学硬编码。
我真的不知道逻辑。我认为逻辑结果正好相反。
虽然 Xcode 总是报告,
[Assert] 尝试在表格视图上调用 -cellForRowAtIndexPath: 在更新其可见单元格的过程中,这是不允许的。在 UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate 处创建一个符号断点以在调试器中捕获此问题并查看导致此问题发生的原因。也许您正试图从表格视图回调中向表格视图询问特定行的单元格?表视图:;层 = ;内容偏移:0, 19;内容大小:314, 836;调整后的内容插入:127.66666666666667, 0, 127.33333333333331, 0;数据源: ;层 = >>
如何改进代码?
我还有一个想法,
访问pickerView的子视图来做它
如何做的更整齐?
【问题讨论】:
请查看***.com/q/47048600/10150796 效果不如我,pickerView.selectedRow(inComponent: component) == row
,你可以查看我的代码。
我的代码在设备中崩溃,在模拟器上运行。
【参考方案1】:
这对我有用:
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
let label = UILabel()
label.text = "\(value(forRow: row))"
label.textColor = UIColor.black
DispatchQueue.main.async // chance color of the middle row
if let label = pickerView.view(forRow: row, forComponent: component) as? UILabel
label.textColor = UIColor.white
return label
幕后的实际工作原理:
UIPickerView
包含 3 个不同的 UITableViews
。对于顶部、中间和底部部分(我的情况是转换的,不要介意)。
函数viewForRow
提供者返回view
,但你不知道view
提供给哪个部分。但是,当您通过pickerView.view(forRow: row, forComponent: component)
请求view
时,它总是会返回中间的那个,然后您就可以进行造型了。它在DispatchQueue.main.async
中的原因是您必须等到pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
结束,通过将其安排到渲染结束queue
。
【讨论】:
以上是关于如何使 UIPickerView.viewForRow 在中心突出显示,重置行灰色?的主要内容,如果未能解决你的问题,请参考以下文章