【问题标题】:Overriding highlighted selection in UIPickerView覆盖 UIPickerView 中突出显示的选择
【发布时间】:2009-06-05 22:30:18
【问题描述】:

我有一个自定义的UIPickerView 我使用:

-(UIView *)pickerView:(UIPickerView *)pickerView
       viewForRow:(NSInteger)row
     forComponent:(NSInteger)component 
      reusingView:(UIView *)view

UILabels 填充选择器。有没有办法禁用触摸时突出显示所选行的行为?

我认为这是UIPickerView 中固有的底层UITableViewCell 的属性,我找不到改变它的方法。

【问题讨论】:

    标签: iphone cocoa-touch uipickerview


    【解决方案1】:

    您需要确保您的自定义视图具有以下属性:

    1. 需要根据您的委托方法——pickerView:rowHeightForComponent:pickerView:widthForComponent:,将其调整为 UIPickerView 期望的相同尺寸。如果您未指定自定义高度,则默认高度为 44。
    2. 背景颜色必须是[UIColor clearColor]
    3. 视图必须捕获所有触摸。

    使用UILabel 实例作为自定义视图时的一个问题是UILabel 默认userInteractionEnabledNO(另一方面,UIView 将此属性默认为YES)。

    基于这些要求,Halle 的示例代码可以重写如下。此示例还正确地重用了先前创建的视图,这是快速滚动性能所必需的。

    - (UIView *)pickerView:(UIPickerView *)pickerView
                viewForRow:(NSInteger)row
              forComponent:(NSInteger)component
               reusingView:(UIView *)view {
    
      UILabel *pickerRowLabel = (UILabel *)view;
      if (pickerRowLabel == nil) {
        // Rule 1: width and height match what the picker view expects.
        //         Change as needed.
        CGRect frame = CGRectMake(0.0, 0.0, 320, 44);
        pickerRowLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
        // Rule 2: background color is clear. The view is positioned over
        //         the UIPickerView chrome.
        pickerRowLabel.backgroundColor = [UIColor clearColor];
        // Rule 3: view must capture all touches otherwise the cell will highlight,
        //         because the picker view uses a UITableView in its implementation.
        pickerRowLabel.userInteractionEnabled = YES;
      }
      pickerRowLabel.text = [pickerDataArray objectAtIndex:row];  
    
      return pickerRowLabel;
    }
    

    【讨论】:

      【解决方案2】:

      UILabeluserInteractionEnabled 属性设置为YES 修复了突出显示问题,但它也禁用了UIPickerView 自动滚动以选择已触摸的行。

      如果您想禁用突出显示行为,但保持UIPickerView 的默认自动滚动功能,请在UIPickerView 中包含的UITableCell 实例中调用setShowSelection 函数。一种方法是继承UILabel 类,类似于以下内容:

      PickerViewLabel.h -

      #import <UIKit/UIKit.h>
      
      @interface PickerViewLabel:UILabel 
      {
      }
      
      @end
      

      PickerViewLabel.m -

      #import "PickerViewLabel.h"
      
      @implementation PickerViewLabel
      
      - (void)didMoveToSuperview
      {
       if ([[self superview] respondsToSelector:@selector(setShowSelection:)])
       {
        [[self superview] performSelector:@selector(setShowSelection:) withObject:NO];
       }
      }
      
      @end
      

      然后,在您之前在 pickerView:viewForRow:forComponent:reusingView: 中返回 UILabel 的实例的地方,返回 PickerViewLabel 的实例。例如,使用来自Doug 的代码,您可以将所有“UILabel”的大小写替换为“PickerViewLabel”。请记住删除pickerRowLabel.userInteractionEnabled = YES; 行。

      【讨论】:

      • 嗨,克里斯汀,我实现了与上面相同的代码,但在所选行的两端仍然出现蓝色选择。当我尝试调试代码时,我发现没有在任何地方调用 didMoveToSuperview。你能帮助我吗?谢谢。
      • 嘿Shailesh,很难说没有看到你的代码,但我有一些关于为什么它不会被调用的想法。 'didMoveToSuperview' 是 UIView 的一个函数,它会在任何时候从视图中添加或删除 UIView 时自动调用。您的自定义视图是否肯定会添加到屏幕上?如果您进行快速测试并将您的类的实例添加为 UIViewController 视图的子视图,您是否看到调用了“didMoveToSuperview”?如果没有,我猜你在函数声明的某个地方有错字。
      【解决方案3】:

      我猜你可能想看看 UIPickerView 的“showsSelectionIndicator”属性

      【讨论】:

      • showsSelectionIndicator 负责在选择器返回的值上方显示蓝色条。不幸的是,它与底层的 UITableViewCell 结构无关。
      【解决方案4】:

      我不确定是否有一种简单的方法可以删除选择反馈,但是如果您将标签的背景设为白色并将其调整为与蓝色选择矩形相同的尺寸,则可以将其覆盖:

      - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
      
          UILabel *pickerRowLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 316, 40)];
          pickerRowLabel.backgroundColor = [UIColor whiteColor];
          pickerRowLabel.text = [pickerDataArray objectAtIndex:row];  
          [self.view addSubview:pickerRowLabel];
      
          return pickerRowLabel;
      
      }
      

      标签的宽度为 316,除了每边的一小块蓝色外,标签都覆盖了所有内容,在 320 处,它完全覆盖了选择反馈,但它也开始覆盖了一些外轮渐变,这可能会或可能不会打扰你。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-17
        • 2013-04-26
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多