我必须更改UIPickerView
中所选行的颜色。
我确实设法改变了颜色,我知道这个问题已经有了几个回复,无论如何那些不满足我:对于那些实现,挑选视图的动画是毛病,我不喜欢它。 / p>
这是当前解决方案的代码
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
var label: UILabel
if view == nil {
label = UILabel()
} else if view is UILabel {
label = view as! UILabel
} else {
label = UILabel()
}
let title: NSAttributedString
if self.model?.selectedValue == row {
title = UIPickerView.attributedString(with: .selectedRow, text: "\(model?.years[row] ?? 0)")
} else {
title = UIPickerView.attributedString(with: .unselectedRow, text: "\(model?.years[row] ?? 0)")
}
label.attributedText = title
return label
}
当用户滚动时,我会重新加载组件。
但是正如您在下面的图片中所看到的,当用户滚动时,绿色区域会移动,绿色标签位于选择器指示器下方并且所选行为黑色的时间段为几分之一。
我想要的是选择器指示器内的所有内容都是绿色,而外部保持默认的灰色阴影。
我该如何实现?
答案 0 :(得分:1)
您应该使用attributedTitleForRow
代替,而不需要使用NSAttributedString
创建自己的标签。在didSelectRow
中重新加载所有组件,以便能够重置所有颜色,并将新选择的颜色设置为绿色。
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let color = (row == pickerView.selectedRow(inComponent: component)) ? UIColor.green : UIColor.black
return NSAttributedString(string: self.model[row], attributes: [NSForegroundColorAttributeName: color])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}
答案 1 :(得分:0)
您可以简单地使用此代码
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = view as? UILabel ?? UILabel()
if pickerView.selectedRow(inComponent: component) == row {
label.backgroundColor = UIColor.green
label.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
label.layer.cornerRadius = 18
label.layer.masksToBounds = true
label.textColor = .white
label.text = String(numbers[row])
label.textAlignment = .center
}else {
label.layer.cornerRadius = 25
label.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
label.layer.cornerRadius = 18
label.layer.masksToBounds = true
label.textColor = .white
label.text = String(numbers[row])
label.textAlignment = .center
}
return label
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
}
答案 2 :(得分:0)
效果更好,但性能稍差。
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
}
}