如何使 UIPickerView.viewForRow 在中心突出显示,重置行变灰?
How to make UIPickerView.viewForRow highlighted in the center , the reset row gray?
如何让它更漂亮?
如下图:中心行突出显示,其余行灰色。
代码如下:
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
}
}
中的更多代码
我需要使用func pickerView(_ pickerView: UIPickerView, viewForRow
,因为
上面的代码工作正常,缺点是它计算量大,并且用一些数学进行了硬编码。
我真的不懂逻辑。我认为逻辑结果恰恰相反。
而 Xcode 总是报告,
[Assert] Attempted to call -cellForRowAtIndexPath: on the table view while it was in the process of updating its visible cells, which is not allowed. Make a symbolic breakpoint at UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate to catch this in the debugger and see what caused this to occur. Perhaps you are trying to ask the table view for a cell from inside a table view callback about a specific row? Table view: ; layer = ; contentOffset: {0, 19}; contentSize: {314, 836}; adjustedContentInset: {127.66666666666667, 0, 127.33333333333331, 0}; dataSource: ; layer = >>
如何改进代码?
我有别的想法,
访问 pickerView 的子视图来完成它
如何做的更整齐?
这对我有用:
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
。上中下部分(我的case是改造过的,别介意)
函数viewForRow
提供者returnsview
,但你不知道view
是为哪个部分提供的。但是当你通过 pickerView.view(forRow: row, forComponent: component)
请求 view
时,它总是 returns 你在中间,然后你就可以做你的造型了。它在 DispatchQueue.main.async
中的原因是您必须等到 pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
结束,方法是将其安排到渲染的末尾 queue
.
如何让它更漂亮?
如下图:中心行突出显示,其余行灰色。
代码如下:
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
}
}
中的更多代码
我需要使用func pickerView(_ pickerView: UIPickerView, viewForRow
,因为
上面的代码工作正常,缺点是它计算量大,并且用一些数学进行了硬编码。
我真的不懂逻辑。我认为逻辑结果恰恰相反。
而 Xcode 总是报告,
[Assert] Attempted to call -cellForRowAtIndexPath: on the table view while it was in the process of updating its visible cells, which is not allowed. Make a symbolic breakpoint at UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate to catch this in the debugger and see what caused this to occur. Perhaps you are trying to ask the table view for a cell from inside a table view callback about a specific row? Table view: ; layer = ; contentOffset: {0, 19}; contentSize: {314, 836}; adjustedContentInset: {127.66666666666667, 0, 127.33333333333331, 0}; dataSource: ; layer = >>
如何改进代码?
我有别的想法,
访问 pickerView 的子视图来完成它
如何做的更整齐?
这对我有用:
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
。上中下部分(我的case是改造过的,别介意)
函数viewForRow
提供者returnsview
,但你不知道view
是为哪个部分提供的。但是当你通过 pickerView.view(forRow: row, forComponent: component)
请求 view
时,它总是 returns 你在中间,然后你就可以做你的造型了。它在 DispatchQueue.main.async
中的原因是您必须等到 pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
结束,方法是将其安排到渲染的末尾 queue
.