如何使 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 在中心突出显示,重置行灰色?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 RelativeLayout 半透明但不使活动

如何用word使图片上下居中

如何使图像自动调整大小,使宽度为 100% 并相应调整高度?

如何使 UISegmentedcontrol 透明?

如何使 textarea 填充 div 块?

如何使 UITableViewCell 显示为禁用?