在 Swift 中为选定的 UIPickerView 行设置动画背景颜色

Posted

技术标签:

【中文标题】在 Swift 中为选定的 UIPickerView 行设置动画背景颜色【英文标题】:Animate background color of selected UIPickerView Row in Swift 【发布时间】:2018-04-11 13:39:50 【问题描述】:

我想用动画改变 UIPickerView 中选定行的背景颜色。我在选择新行时重新加载所有组件,并且在 viewForRow 函数中如果选择了当前行,我将其背景颜色设置为红色。但是,它看起来像在错误中。第一个屏幕截图是我想要实现的,第二个屏幕截图是在我的应用程序中。顺便说一句,如果我能用动画设置红色就太好了

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    pickerView.reloadAllComponents()


func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView 
    let view = UIView()
    view.frame = CGRect(x: 0, y: 0, width: width, height: height)

    let label = UILabel()
    label.frame = CGRect(x: 0, y: 0, width: height, height: height)
    label.textAlignment = .center
    label.font = UIFont.systemFont(ofSize: 30)
    label.text = numbers[row]
    view.addSubview(label)

    view.transform = CGAffineTransform(rotationAngle: 90 * (.pi/180))
    if pickerView.selectedRow(inComponent: component) == row 
    label.attributedText =  NSAttributedString(string: numbers[row], attributes: [NSAttributedStringKey.font:UIFont.systemFont(ofSize: 30),NSAttributedStringKey.foregroundColor:UIColor.white])
        view.backgroundColor = UIColor.red
    
    return view

【问题讨论】:

【参考方案1】:

一种稍微不同的方法,因为我找不到一种平滑的方法来为选定行的背景设置动画。可以做到,但改进不大,所以试试这个:

override func viewDidLoad() 
    //...

    /*
     Create a colored `view` that stays bang in the center on top
     of the `pickerView`.
     The `pickerView` will scroll behind it normally and no need
     for animating background color or even reloading
     */
    createHighlightView()


func createHighlightView() 
    let highlightView = UIView(frame: CGRect.zero)
    highlightView.backgroundColor = UIColor.red.withAlphaComponent(0.2)

    /*
     Now lets programmatically add constraints
     */
    highlightView.translatesAutoresizingMaskIntoConstraints = false
    pickerView.addSubview(highlightView)

    //HightLight View's width
    highlightView.addConstraint(NSLayoutConstraint(item: highlightView,
                                                   attribute: .width,
                                                   relatedBy: .equal,
                                                   toItem: nil,
                                                   attribute: .notAnAttribute,
                                                   multiplier: 1,
                                                   constant: width))

    //HightLight View's height
    highlightView.addConstraint(NSLayoutConstraint(item: highlightView,
                                                   attribute: .height,
                                                   relatedBy: .equal,
                                                   toItem: nil,
                                                   attribute: .notAnAttribute,
                                                   multiplier: 1,
                                                   constant: height))

    //HightLight View should be bang center-aligned with pickerView
    pickerView.addConstraint(NSLayoutConstraint(item: highlightView,
                                                attribute: .centerX,
                                                relatedBy: .equal,
                                                toItem: pickerView,
                                                attribute: .centerX,
                                                multiplier: 1,
                                                constant: 0))
    pickerView.addConstraint(NSLayoutConstraint(item: highlightView,
                                                attribute: .centerY,
                                                relatedBy: .equal,
                                                toItem: pickerView,
                                                attribute: .centerY,
                                                multiplier: 1,
                                                constant: 0))


现在您的代表可以很简单:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    //no need to reload
    //do whatever else you want


func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView 
    /*
     Just return a `UILabel`. No need to put it in a `UIView`.
     Nothing special either, just slap text into it
     */

    var label = view as? UILabel

    if label == nil 
        label = UILabel()

        //All the rest are safe force unwraps so chill tf out
        label!.frame = CGRect(x: 0, y: 0, width: height, height: height)
        label!.textAlignment = .center
        label!.font = UIFont.systemFont(ofSize: 30)

        label!.transform = CGAffineTransform(rotationAngle: 90 * (.pi/180))
    

    label!.text = arrDatasource[row]

    return label!

【讨论】:

我明白了。但是在这个解决方案中,我猜我不能为pickerview设置背景颜色?它会覆盖视图,对吗? @EmreÖnder :) 但如果你有具体的设计,请告诉我,我会看看能不能给你一些东西 我正在尝试对这个设计进行精确编码; i.stack.imgur.com/feVei.png 我找到了一个图书馆; github.com/AvanzaBank/AZAPicker 我想我可以用这个库来实现它。当然,如果我能学会怎么做就太好了:) @EmreÖnder 查看AZAPicker 的代码,它是UIScrollViewUIStackView,中间有一个蒙版视图。但是,是的,根据您的设计,它是平坦的,而不是像默认的 UIPickerView 那样弯曲。随它去吧。分叉它并根据您的目的修改掩码。

以上是关于在 Swift 中为选定的 UIPickerView 行设置动画背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

jQuery:在 Datepicker 中为选定的日期添加样式

如何在角度6中为选择选项设置默认选定对象

如何在 Laravel 5.5 中为选定的请求类设置自定义响应

在 Vue.js 2.x 中为选定的 NPM 包禁用 eslint

如何使用“构造函数”在“选择子句”中为多个表的选定列编写HQL JOIN查询

word中为选定文本加边框和底纹