如何通过html select标签创建UIPickerView的对象引用

时间:2013-10-30 14:06:05

标签: html ios uiwebview xcode5

我有一个UIWebview包含一个html“select”标签,它在屏幕上显示为dropdown list

当我点击下拉列表时,UIWebview会自动显示一个UIWebSelectSinglePicker视图,显示为default OS pickerview

我想更改选择器视图背景颜色和文本颜色。我怎样才能实现这个目标?

我试图收听UIKeyboardWillShowNotification事件,但此时此视图尚未创建。

提前感谢任何帮助。

2 个答案:

答案 0 :(得分:4)

我设法自己解决了这个问题。

如果有人还想动态更改UIPickView,请查看:

首先,在UIKeyboardWillShowNotification事件上添加一个监听器。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_pickerViewWillBeShown:) name:UIKeyboardWillShowNotification object:nil];

其次,当通知被触发时,延迟后调用更改背景颜色方法。 < - 这非常重要,如果没有延迟的调用方法,那时pickview就不存在了。

- (void)_pickerViewWillBeShown:(NSNotification*)aNotification {
   [self performSelector:@selector(_resetPickerViewBackgroundAfterDelay) withObject:nil   afterDelay:0];
}

第三,浏览UIApplication窗口,找出pickerView。你可以改变你想要的pickerView。

-(void)_resetPickerViewBackgroundAfterDelay
{
  UIPickerView *pickerView = nil;
  for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
    for (UIView *uiView in [uiWindow subviews]) {
      pickerView = [self _findPickerView:uiView];
    }
  }

  if (pickerView){
    [pickerView setBackgroundColor:UIColorFromRGB(0x00FF00)];
  }
}

(UIPickerView *) _findPickerView:(UIView *)uiView {
  if ([uiView isKindOfClass:[UIPickerView class]] ){
    return (UIPickerView*) uiView;
  }
  if ([uiView subviews].count > 0) {
    for (UIView *subview in [uiView subviews]){
      UIPickerView* view = [self _findPickerView:subview];
      if (view)
        return view;
    }
  }
  return nil;
}

希望它会有所帮助。

答案 1 :(得分:1)

我相信我已经提出了解决这个问题的替代解决方案。在某些情况下,建议使用其他解决方案,其中标签颜色显示不正确(使用系统默认值而不是覆盖的颜色)。滚动项目列表时会发生这种情况。

为了防止这种情况发生,我们可以使用方法调配来修复源头的标签颜色(而不是在它们已经创建后修补它们)。

显示UIWebSelectSinglePicker(如您所述),它实现了UIPickerViewDelegate协议。该协议负责提供NSAttributedString实例,这些实例通过- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component方法显示在选择器视图中。通过使用我们自己的实现来实现,我们可以覆盖标签的外观。

为此,我在UIPickerView上定义了一个类别:

@implementation UIPickerView (LabelColourOverride)

- (NSAttributedString *)overridePickerView:(UIPickerView *)pickerView 
                     attributedTitleForRow:(NSInteger)row 
                              forComponent:(NSInteger)component
{
    // Get the original title
    NSMutableAttributedString* title = 
        (NSMutableAttributedString*)[self overridePickerView:pickerView 
                                       attributedTitleForRow:row 
                                                forComponent:component];

    // Modify any attributes you like. The following changes the text colour.
    [title setAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} 
                   range:NSMakeRange(0, title.length)];

    // You can also conveniently change the background of the picker as well. 
    // Multiple calls to set backgroundColor doesn't seem to slow the use of 
    // the picker, but you could just as easily do a check before setting the
    // colour to see if it's needed.
    pickerView.backgroundColor = [UIColor yellowColor];

    return title;
}

@end

然后使用方法调配(see this answer for reference)我们交换实现:

[Swizzle swizzleClass:NSClassFromString(@"UIWebSelectSinglePicker") 
               method:@selector(pickerView:attributedTitleForRow:forComponent:) 
               forClass:[UIPickerView class] 
               method:@selector(overridePickerView:attributedTitleForRow:forComponent:)];

这是我根据上面的链接开发的Swizzle实现。

@implementation Swizzle

+ (void)swizzleClass:(Class)originalClass 
              method:(SEL)originalSelector 
            forClass:(Class)overrideClass 
              method:(SEL)overrideSelector
{
    Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
    Method overrideMethod = class_getInstanceMethod(overrideClass, overrideSelector);
    if (class_addMethod(originalClass, 
                        originalSelector,
                        method_getImplementation(overrideMethod),
                        method_getTypeEncoding(overrideMethod))) {
        class_replaceMethod(originalClass,
                            overrideSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } 
    else {
        method_exchangeImplementations(originalMethod, overrideMethod);
    }
}

@end

这样做的结果是,当请求一个标签时,我们会调用我们的覆盖函数,它调用原始函数,这很容易就会给我们返回一个可变的NSAttributedString,我们可以根据需要修改它。如果我们想要并且只保留文本,我们可以完全替换返回值。 Find the list of attributes you can change here

此解决方案允许您通过单个调用全局更改应用程序中的所有Picker视图,从而无需为需要此代码的每个视图控制器注册通知(或定义基类来执行相同操作)。