Swift 中所选 UIPickerView 行的动画背景颜色

Animate background color of selected UIPickerView Row in Swift

我想用动画更改 UIPickerView 中选定行的背景颜色。 I'm reloading all components when a new row selected and in viewForRow function If current row is selected one, I make Its' background color to red.但是,它看起来像在错误中。第一个屏幕截图是我想要实现的,第二个是在我的应用程序中。顺便说一句,如果我能用动画设置红色就太好了

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
}

一种略有不同的方法,因为我找不到一种平滑的方法来为选定行的背景制作动画。可以做到,但改善不大,所以试试看:

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!
}