如何更改 UIPickerView 中选定行的颜色
Posted
技术标签:
【中文标题】如何更改 UIPickerView 中选定行的颜色【英文标题】:How to change color of selected row in UIPickerView 【发布时间】:2009-05-21 23:45:45 【问题描述】:好吧,也许我错过了一些非常简单的东西,如果是这种情况,我深表歉意,但是,我已经用谷歌搜索了标题的每个排列,但没有找到!因此,这只是我想要做的:更改标签的背景颜色我在选择该行时,我使用的是2个组件Pickerview中的行视图。所以我认为这会起作用:
if (row == [pickerview selectedRowForComponent])
viewlabel.backgroundColor = redcolor;
但这不起作用。它似乎随意选择要着色的行,有时甚至会出现错误的访问错误。我试过所有不同的条款都没有效果!任何建议将不胜感激!
这是完整的方法:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
if (component == kNumberComponent)
#define PICKER_LABEL_FONT_SIZE 24
#define PICKER_LABEL_ALPHA 1.0
// UIFont *font = [UIFont boldSystemFontOfSize:PICKER_LABEL_FONT_SIZE];
UIFont *font = [ UIFont fontWithName:@"AppleGothic" size:24];
UILabel *carsLabel =[ [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 75, 50) ]autorelease];
//[picker selectRow:row inComponent:component animated:YES];
NSString *pickerText = [self.numbers objectAtIndex:(int)row];
carsLabel.text = pickerText;
carsLabel.textAlignment = UITextAlignmentCenter;
NSLog(@"carsLabel = %@",carsLabel.text);
//carsLabel.text = @"maybe because the string isn't long enough";
carsLabel.textColor = [UIColor blackColor];
carsLabel.font = font;
carsLabel.opaque = YES;
[view addSubview:carsLabel];
return carsLabel;
else
UIFont *font = [ UIFont fontWithName:@"AppleGothic" size:18];
UILabel *carsLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 225, 50)] autorelease];
id fact = [self.facts objectAtIndex:(int)row];
NSString *pickerText = @"Dictionary Entry";
if ( [fact isKindOfClass:[NSString class]])
pickerText = [self.facts objectAtIndex:(int)row];
carsLabel.text = pickerText;
carsLabel.textAlignment = UITextAlignmentCenter;
NSLog(@"carsLabel = %@",carsLabel.text);
//carsLabel.text = @"maybe because the string isn't long enough";
carsLabel.textColor = [UIColor blackColor];
carsLabel.font = font;
if ( row == 0)
carsLabel.backgroundColor = [UIColor redColor];
//carsLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blackboard.png"]];;
carsLabel.opaque = YES;
[view addSubview:carsLabel];
return carsLabel;
return nil;
【问题讨论】:
【参考方案1】:一般情况下,我使用这种方法:
我使用自定义视图来显示行项
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
UILabel *label = (id)view;
if (!label)
label= [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.text = _arrayStringPicker[row];
return label;
我更改所选行的颜色:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
UILabel *labelSelected = (UILabel*)[pickerView viewForRow:row forComponent:component];
[labelSelected setTextColor:[UIColor redColor]];
【讨论】:
【参考方案2】:Swift 实现
extension PickerViewController: UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString?
var color: UIColor!
if pickerView.selectedRowInComponent(component) == row
color = UIColor.redColor()
else
color = UIColor.blackColor()
let attributes: [String: AnyObject] = [
NSForegroundColorAttributeName: color,
NSFontAttributeName: UIFont.systemFontOfSize(15)
]
return NSAttributedString(string: rows[row], attributes: attributes)
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
//this will trigger attributedTitleForRow-method to be called
pickerView.reloadAllComponents()
【讨论】:
【参考方案3】:viewForPicker 的正确格式是:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
UILabel *label = (UILabel*) view;
if (label == nil)
label = [[UILabel alloc] init];
[label setText:@"Whatever"];
// This part just colorizes everything, since you asked about that.
[label setTextColor:[UIColor whiteColor]];
[label setBackgroundColor:[UIColor blackColor]];
CGSize rowSize = [pickerView rowSizeForComponent:component];
CGRect labelRect = CGRectMake (0, 0, rowSize.width, rowSize.height);
[label setFrame:labelRect];
return label;
上面代码的问题是:它为标签着色,而不是选择器本身。因此,当您滚动到一端或另一端时,会有一个空白点,您可以在其中看到白色背景。设置 [myPicker setBackgroundColor...] 并没有达到人们希望的效果。
【讨论】:
【参考方案4】:// 我们想要的框架的 CGRectMake 值
UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height)];
// add the UIPickerView to your viewcontroller [mainView addSubview:myPickerView];
// set the selectionindicator to none myPickerView.showsSelectionIndicator = NO;
// 定义我们想要使用的图像
UIImage *selectorImage = [UIImage imageNamed:@"selectionIndicator.png"];
UIView *customSelector = [[UIImageView alloc] initWithImage:selectorImage];
// 将 x 和 y 值设置为 UIPickerView 上要放置图像的点
// 将宽度和高度值设置为图像的宽度和高度
customSelector.frame = CGRectMake(10,(myPickerView.bounds.size.height / 2) + 16, self.view.bounds.size.width – 10, 47);
// 将自定义 selectionIndicator 也添加到同一个视图控制器中
[mainView addSubview:customSelector];
【讨论】:
【参考方案5】:解决了!声明 2 个实例变量:selectedView 和 oldView。然后下面的代码就可以了:
if (self.oldView != nil)
self.oldView.backgroundColor = [UIColor clearColor];
self.selectedView = [picker viewForRow:row forComponent:kNumberComponent];
self.selectedView.backgroundColor = [UIColor redColor];
[self.selectedView setNeedsDisplay];
self.oldView = self.selectedView;
【讨论】:
在 UIPickerView 的viewForRow
方法中【参考方案6】:
调用UIPickerView
实例的-viewForRow:forComponent:
方法获取UIView *
对象。然后设置该视图的背景UIColor
。
【讨论】:
我相信我已经尝试过了,但我又试了一次 还要确保您已将您的 UIView(包含 UIPickerView)设置为选取器视图的委托,并且您已指定UIView
将实现 UIPickerViewDelegate
合约。
嗨,Alex,我在pickerviewcontroller 中有上面的代码,并在loadView 方法中设置了pickerview.delegate = self。我尝试了 didSelectRow 方法: UIView *selectedView = [numberFactsPicker viewForRow:numberRow forComponent:kFactComponent]; selectedView.backgroundColor = [UIColor redColor];不知何故,我想我可能需要将它作为子视图添加回来?
也许你可以检查 *selectedView 是否为 nil。也许有些东西连接不正确。也许使用调试器或 NSLog 语句来检查事物的值,以及确保您的委托方法正在被调用。
设置 viewForRow 的背景颜色主要是可行的,但是在第一个和最后一个项目的情况下,您仍然可以看到选取器的白色背景,“离开卷轴边缘”。可悲的是,设置 [myPickerView setBackGroundColor:[UIColor blackColor]] (或任何颜色)并没有达到人们希望的效果。【参考方案7】:
@alessandro-pirovano 答案的 Swift 版本
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
let rowSize = pickerView.rowSize(forComponent: component)
let width = rowSize.width
let height = rowSize.height
let frame = CGRect(x: 0, y: 0, width: width, height: height)
let label = UILabel(frame: frame)
label.textAlignment = .center
label.text = rows[row]
return label
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
guard let label = pickerView.view(forRow: row, forComponent: component) as? UILabel else
return
label.backgroundColor = .orange
【讨论】:
【参考方案8】:不清楚您将上述代码放在哪里。是在-pickerView:viewForRow:forComponent:reusingView:
吗?这是它应该在的地方。您确定要维护指向该特定视图标签的指针吗?您正在崩溃的事实表明您可能不是。更大的代码块,包括你把它放在哪里,会很有帮助。
【讨论】:
Rob,我已经发布了完整的方法,再次感谢您的任何建议! 我想你误解了这个委托方法是如何工作的。 pickerView 给你一个reusingView
。您正在使用-addSubView:
对其进行修改,但您返回的是不同的视图(UILabel
)。您应该在这里做的第一件事是摆脱对-addSubView:
的调用。【参考方案9】:
这对我有用:
-
将
UIView
作为子视图添加到您的UIPickerView
将其限制为使用 UIPickerView
输入的 Y 并且宽度相同
给它高度等于pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat
中返回的高度
将其设为半透明并按您的方式着色
*其他解决方案(带有行的自定义视图或行的属性字符串)在快速滚动时存在错误。
【讨论】:
【参考方案10】:UIPickerView 有委托为行和组件的标题设置 NSAttributeString,我们可以设置属性颜色,如下所示:
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
NSDictionary *attrs = @NSForegroundColorAttributeName : [UIColor redColor];
NSString *title = @"title"
return [[NSAttributedString alloc] initWithString:title attributes:attrs];
【讨论】:
【参考方案11】:扩展 Alessandro Pirovano 的回答;
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
UILabel *labelSelected = (UILabel*)[pickerView viewForRow:row forComponent:component];
[labelSelected setTextColor:[UIColor redColor]];
labelSelected.superview.backgroundColor = [UIColor yellowColor];
【讨论】:
这对我来说按预期工作。文本标签有颜色,行背景也有颜色。唯一需要注意的是,您需要在创建选择器视图时强制选择,以便初始显示也具有选定的颜色行。以上是关于如何更改 UIPickerView 中选定行的颜色的主要内容,如果未能解决你的问题,请参考以下文章
在 UIPickerView 中更改选定行的颜色,滚动时也是如此
如何在 iOS 14 中更改 UIPickerView 选择的色调颜色?
在 Swift 中为选定的 UIPickerView 行设置动画背景颜色