无法粘贴 UIPicker 文本着色

Posted

技术标签:

【中文标题】无法粘贴 UIPicker 文本着色【英文标题】:Can't get UIPicker text coloring to stick 【发布时间】:2015-08-05 17:09:38 【问题描述】:

我正在尝试获取一个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;

还有一些额外的东西,让两个***紧密对齐,但有一点间距(透明周期)。它主要工作:

最初,它看起来很完美,绿色选择和白色/灰色其他选择。问题是当我滚动***时,它们并不总是以绿色结束。有时他们会这样做,但并非总是如此。可以看出,有时滚动的值即使不再被选中也会保持绿色(参见右上角的09)。

我该怎么做才能使绿色只保持在选定的行上?

【问题讨论】:

你有一个调试器。调试!我的猜测是在viewForRow 内调用selectedRowInComponent 并不总是有效。添加一些日志记录,看看它是否始终正确显示。 一些NSLoging 表明,是的,当它调用pickerView:viewForRow:forComponent:reusingView: 方法时,它有点虚伪。有时根本没有(它已经有了一些东西),而且通常在更新选择之前。 谨慎使用reloadComponent,显然会导致这些缓存被刷新,迫使它再次调用所述方法并获得“最新”的正确呈现。有人应该把它放在Answer 中以获得积分... 您知道您可以回答自己的问题吗? (不过,我确实认为@Idali 已经对此事提出了意见,所以你可以接受这个答案。或者你可以两者都做。) 是的,我自己回答的问题很多。只是想分享一点财富。我们并不是都有 100K 点。 :) 【参考方案1】:

如果一行最初是绿色的,如果您向上或向下滚动直到该行仍然可见,它将保持绿色,因为 viewForRow:(NSInteger)row forComponent: 不会在该行上调用(它将是如果此行以前不可见并且需要可见,则调用)...

虽然您需要在 selectedRowinCompoment 中将绿色设置为选中,但您还需要从旧的选定行中删除绿色(以防它仍然可见)。

【讨论】:

【参考方案2】:

@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 文本着色的主要内容,如果未能解决你的问题,请参考以下文章

无法将 Mac 上的文本粘贴到 ios 模拟器 Xcode 12 中?

为啥复制后不能粘贴

Python 模拟键盘 粘贴内容 无法粘贴中文汉字

粘贴前更新剪贴板数据(不是“粘贴”事件)

如何不为“复制/粘贴”UITextView 选择文本

Summernote 编辑器中的粘贴事件未触发 - 无法获取粘贴值