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

时间:2018-04-11 13:39:51

标签: ios swift uiview uipickerview

我想用动画更改UIPickerView中所选行的背景颜色。当我选择一个新行并在viewForRow函数中时,我正在重新加载所有组件如果选择了当前行,我将其背景颜色设置为红色。但是,它看起来像bug。第一个屏幕截图是我想要实现的,第二个是在我的应用程序中。顺便说一下,如果我可以用动画设置那种红色

,它会很棒
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
}

First Second

1 个答案:

答案 0 :(得分:1)

略有不同的方法,因为我无法找到一种平滑的方式来动画所选行的背景。它可以完成,但没有太大的改进,所以试试看:

Highlighted PickerView

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