无法让 UIPicker 文本着色粘贴
Can't get UIPicker text coloring to stick
我正在尝试获取 UIPicker
以绿色文本显示所选行。我使用 pickerView:viewForRow:forComponent:reusingView:
方法为其创建一个 UILabel:
- (UIView*) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *label = (UILabel*)view;
if (label == nil) {
label = [UILabel new];
label.font = [UIFont boldSystemFontOfSize: 24];
label.adjustsFontSizeToFitWidth = YES;
}
UIColor *color = (row == [pickerView selectedRowInComponent: component]) ? RGBx(0x579B2F) : UIColor.whiteColor;
label.textAlignment = component == 0 ? NSTextAlignmentRight : NSTextAlignmentLeft;
NSMutableAttributedString *string;
if (component == 0) {
string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%3lu.", row]];
[string addAttribute:NSForegroundColorAttributeName value: color range:NSMakeRange(0, string.length - 1)];
[string addAttribute:NSForegroundColorAttributeName value: [UIColor clearColor] range:NSMakeRange(string.length - 1,1)];
}
else {
string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@".%02lu", row % 60]];
[string addAttribute:NSForegroundColorAttributeName value: [UIColor clearColor] range:NSMakeRange(0,1)];
[string addAttribute:NSForegroundColorAttributeName value: color range:NSMakeRange(1,string.length - 1)];
}
label.attributedText = string;
return label;
}
里面还有一些额外的东西,让两个轮子紧密对齐,但有一点间距(透明周期)。它主要有效:
最初,它看起来很完美,绿色选择和 white/gray 其他选择。问题是当我滚动轮子时,它们并不总是以绿色结束。有时他们会这样做,但并非总是如此。可以看出,有时滚动的值会保持绿色,即使它不再被选中(见右上角的09
)。
我该怎么做才能只保留绿色并始终在选定的行上?
如果一行最初是绿色的,如果向上或向下滚动直到该行仍然可见,它将保持绿色,因为 viewForRow:(NSInteger)row forComponent: 不会在该行上调用(它如果此行以前不可见且需要可见,则将被调用)...
虽然您需要在 selectedRowinCompoment 中将绿色设置为选中,但您还需要从旧的选定行中移除绿色(以防它仍然可见)。
@idali 诊断问题很好。并提示需要发生什么。但没有给出实际答案。
答案是使用reloadComponent:
(或reloadAllComponents
)。它应该在用户更改选择或您以编程方式更改值的任何时候完成。例如
-(void) pickerView:(UIPickerView*) pickerView didSelectRow:(NSInteger) row inComponent:(NSInteger) component {
[pickerView reloadComponent: component];
}
任何时候你使用 selectRow:inComponent:animated:
:
...
[self.picker selectRow: hours inComponent: 0 animated: YES];
[self.picker reloadAllComponents];
...
我正在尝试获取 UIPicker
以绿色文本显示所选行。我使用 pickerView:viewForRow:forComponent:reusingView:
方法为其创建一个 UILabel:
- (UIView*) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *label = (UILabel*)view;
if (label == nil) {
label = [UILabel new];
label.font = [UIFont boldSystemFontOfSize: 24];
label.adjustsFontSizeToFitWidth = YES;
}
UIColor *color = (row == [pickerView selectedRowInComponent: component]) ? RGBx(0x579B2F) : UIColor.whiteColor;
label.textAlignment = component == 0 ? NSTextAlignmentRight : NSTextAlignmentLeft;
NSMutableAttributedString *string;
if (component == 0) {
string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%3lu.", row]];
[string addAttribute:NSForegroundColorAttributeName value: color range:NSMakeRange(0, string.length - 1)];
[string addAttribute:NSForegroundColorAttributeName value: [UIColor clearColor] range:NSMakeRange(string.length - 1,1)];
}
else {
string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@".%02lu", row % 60]];
[string addAttribute:NSForegroundColorAttributeName value: [UIColor clearColor] range:NSMakeRange(0,1)];
[string addAttribute:NSForegroundColorAttributeName value: color range:NSMakeRange(1,string.length - 1)];
}
label.attributedText = string;
return label;
}
里面还有一些额外的东西,让两个轮子紧密对齐,但有一点间距(透明周期)。它主要有效:
最初,它看起来很完美,绿色选择和 white/gray 其他选择。问题是当我滚动轮子时,它们并不总是以绿色结束。有时他们会这样做,但并非总是如此。可以看出,有时滚动的值会保持绿色,即使它不再被选中(见右上角的09
)。
我该怎么做才能只保留绿色并始终在选定的行上?
如果一行最初是绿色的,如果向上或向下滚动直到该行仍然可见,它将保持绿色,因为 viewForRow:(NSInteger)row forComponent: 不会在该行上调用(它如果此行以前不可见且需要可见,则将被调用)...
虽然您需要在 selectedRowinCompoment 中将绿色设置为选中,但您还需要从旧的选定行中移除绿色(以防它仍然可见)。
@idali 诊断问题很好。并提示需要发生什么。但没有给出实际答案。
答案是使用reloadComponent:
(或reloadAllComponents
)。它应该在用户更改选择或您以编程方式更改值的任何时候完成。例如
-(void) pickerView:(UIPickerView*) pickerView didSelectRow:(NSInteger) row inComponent:(NSInteger) component {
[pickerView reloadComponent: component];
}
任何时候你使用 selectRow:inComponent:animated:
:
...
[self.picker selectRow: hours inComponent: 0 animated: YES];
[self.picker reloadAllComponents];
...