我想用动画更改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
}
答案 0 :(得分: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!
}