Переопределение выделенного выделения в UIPickerView - PullRequest
8 голосов
/ 06 июня 2009

У меня есть пользовательский UIPickerView, где я использую:

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

, чтобы заполнить сборщик UILabels. Есть ли способ отключить поведение выделения выделенной строки при касании?

Я думаю, что это свойство базового UITableViewCell, присущего UIPickerView, и я не могу найти способ изменить его.

Ответы [ 4 ]

16 голосов
/ 16 сентября 2009

Вы должны убедиться, что ваш пользовательский вид имеет следующие свойства:

  1. Его размер должен соответствовать тем же измерениям, которые ожидают UIPickerView в зависимости от ваших методов делегата - pickerView:rowHeightForComponent: и pickerView:widthForComponent:. Высота по умолчанию - 44, если вы не указали собственную высоту.
  2. Цвет фона должен быть [UIColor clearColor].
  3. Вид должен охватывать все касания.

При использовании экземпляров UILabel в качестве настраиваемого представления есть одна ошибка: UILabel по умолчанию userInteractionEnabled - NO (UIView, с другой стороны, по умолчанию это свойство равно YES).

На основании этих требований пример кода из Галле может быть переписан следующим образом. В этом примере также правильно используются ранее созданные представления, что необходимо для быстрой прокрутки.

- (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;
}
12 голосов
/ 23 ноября 2009

Установка свойства userInteractionEnabled для UILabel в YES устраняет проблему выделения, но также отключает автоматическую прокрутку UIPickerView для выбора строки, к которой вы прикоснулись.

Если вы хотите отключить режим выделения, но сохранить функцию автопрокрутки по умолчанию UIPickerView, вызовите функцию setShowSelection в экземплярах UITableCell, содержащихся в UIPickerView. Один из способов сделать это - создать подкласс класса 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

Затем, когда вы ранее возвращали экземпляр UILabel в pickerView:viewForRow:forComponent:reusingView:, возвращайте экземпляр PickerViewLabel. Например, используя код из Doug , вы заменили бы все случаи 'UILabel' на 'PickerViewLabel'. Просто не забудьте удалить строку pickerRowLabel.userInteractionEnabled = YES;.

0 голосов
/ 10 июня 2009

Я не уверен, есть ли простой способ удалить отзыв о выборе, но вы можете скрыть его, если сделаете фон метки белым и измените его размеры до тех же размеров, что и синий прямоугольник выбора:

- (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 она полностью покрывает обратную связь выбора, но также начинает покрывать немного внешних градиентов колеса, которые могут или не могут беспокоить вы.

0 голосов
/ 06 июня 2009

Полагаю, вы можете захотеть взглянуть на свойство "showsSelectionIndicator" UIPickerView

...