2009-06-05 10 views
8

Tôi có một tùy chỉnh UIPickerView nơi tôi sử dụng:Overriding nhấn mạnh lựa chọn trong UIPickerView

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

để cư bộ chọn với UILabels. Có cách nào để vô hiệu hóa hành vi làm nổi bật hàng đã chọn khi chạm vào không?

Tôi nghĩ đây là tài sản của cơ sở UITableViewCell vốn có trong UIPickerView và tôi không thể tìm thấy cách thay đổi nó.

Trả lời

16

Bạn cần phải chắc chắn giao diện tùy chỉnh của bạn có các thuộc tính sau:

  1. Nó cần phải được kích thước với kích thước tương tự rằng UIPickerView hy vọng dựa trên phương pháp đại biểu của bạn - pickerView:rowHeightForComponent:pickerView:widthForComponent:. Chiều cao mặc định là 44 nếu bạn không chỉ định chiều cao tùy chỉnh.
  2. Màu nền phải là [UIColor clearColor].
  3. Chế độ xem phải chụp tất cả các lần chạm.

Một Gotcha khi sử dụng UILabel trường hợp như giao diện tùy chỉnh là giá trị mặc định UILabeluserInteractionEnabled-NO (UIView, mặt khác, giá trị mặc định tài sản này để YES).

Dựa trên các yêu cầu này, mã ví dụ từ Halle có thể được viết lại như sau. Ví dụ này cũng chính xác sử dụng lại các khung nhìn đã tạo trước đó, cần thiết cho hiệu suất cuộn nhanh.

- (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; 
} 
0

Tôi đoán bạn có thể muốn xem xét "showsSelectionIndicator" tài sản của UIPickerView

+0

Chương trìnhSelectionIndicator chịu trách nhiệm hiển thị thanh màu xanh trên giá trị sẽ được chọn bởi bộ chọn. Thật không may là không có gì để làm với cấu trúc UITableViewCell cơ bản. – Jon

0

Tôi không chắc chắn nếu có một cách dễ dàng để loại bỏ các thông tin phản hồi lựa chọn, nhưng bạn có thể che đậy nó nếu bạn thực hiện nền của nhãn trắng và kích thước nó để kích thước tương tự như vùng chọn hình chữ nhật màu xanh:

- (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; 

} 

với chiều rộng 316 nhãn bao gồm tất cả nhưng một mảnh màu xanh trên mỗi bên, và ở 320 nó hoàn toàn bao gồm các lựa chọn thông tin phản hồi nhưng nó cũng bắt đầu bao gồm một chút của gradient bánh xe bên ngoài, có thể hoặc có thể không làm phiền bạn.

12

Thiết lập userInteractionEnabled tài sản của UILabel để YES sửa chữa các vấn đề nổi bật, nhưng nó cũng vô hiệu hóa UIPickerView từ autoscrolling để chọn hàng đó đã được chạm vào.

Nếu bạn muốn vô hiệu hóa hành vi làm nổi bật, nhưng duy trì chức năng tự động kiểm tra mặc định của UIPickerView, hãy gọi hàm setShowSelection trong các trường hợp UITableCell có trong UIPickerView. Một cách để làm điều này là để phân lớp lớp UILabel tương tự như sau:

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 

Sau đó, nơi bạn trước đây đã được trở về một thể hiện của UILabel trong pickerView:viewForRow:forComponent:reusingView:, trở về một thể hiện của PickerViewLabel. Ví dụ: sử dụng mã từ Doug, bạn sẽ thay thế tất cả các trường hợp 'UILabel' bằng 'PickerViewLabel'. Chỉ cần nhớ xóa đường dây pickerRowLabel.userInteractionEnabled = YES;.

+0

Xin chào Christine, tôi đã triển khai cùng mã trên nhưng vẫn chọn màu xanh ở cả hai hàng đã chọn. Khi tôi cố gắng để gỡ lỗi mã, tôi thấy rằng didMoveToSuperview không được gọi là bất cứ nơi nào. Bạn có thể giúp tôi được không? Cảm ơn. – engineer

+0

Hey Shailesh, Thật khó để nói rằng bạn thấy mã của bạn, nhưng tôi có một vài ý tưởng về lý do tại sao nó sẽ không được gọi. 'didMoveToSuperview' là một chức năng của UIView được gọi tự động bất cứ lúc nào mà một UIView được thêm vào hoặc loại bỏ khỏi một lần xem. Chế độ xem tùy chỉnh của bạn có được thêm vào màn hình không? Nếu bạn làm một bài kiểm tra nhanh và thêm một thể hiện của lớp của bạn như là một subview của một UIViewController của xem, bạn có thấy 'didMoveToSuperview' được gọi là sau đó? Nếu không, tôi đoán rằng bạn có lỗi đánh máy ở đâu đó trong khai báo hàm. – Christine

+0

tuyệt vời .... cảm ơn rất nhiều .. u đã cứu mạng tôi và rất nhiều thời gian –