2009-08-17 33 views
16

Tôi sẽ viết điều khiển tùy chỉnh của riêng mình rất khác với UIButton. Nó khác biệt rất nhiều đến mức tôi quyết định viết nó từ đầu. Vì vậy, tất cả các lớp con của tôi là UIControl.Làm cách nào để triển khai cơ chế nhắm mục tiêu hành động để kiểm soát tùy chỉnh?

Khi điều khiển của tôi được chạm vào bên trong, sau đó tôi muốn kích hoạt tin nhắn bằng phương tiện của hành động mục tiêu. Người dùng của lớp đó có thể khởi tạo nó và sau đó thêm một số mục tiêu và hành động cho sự kiện này.

tức là tôi sẽ gọi nội bộ phương thức -fireTargetsForTouchUpEvent. Làm thế nào tôi có thể duy trì cơ chế mục tiêu-hành động này trong lớp học của tôi? Tôi có phải thêm tất cả các mục tiêu và hành động vào mảng của riêng tôi và sau đó chỉ cần gọi bộ chọn (các hành động) trên các đối tượng đích trong một vòng lặp không? Hay có cách nào thông minh hơn để làm điều đó?

Tôi hình dung cung cấp một số phương pháp để thêm mục tiêu và hành động cho một số sự kiện như sự kiện liên lạc đó (tôi nâng cao thủ công bằng cách gọi phương thức nội bộ khi điều đó xảy ra). Bất kỳ ý tưởng?

+0

Thông thường, các điều khiển có một mục tiêu, một bộ chọn cho mỗi sự kiện. Bạn có muốn nhiều hơn? –

+0

Tôi có thể có nhiều hơn, nếu tôi muốn? Tôi nghĩ là có...nhưng không chắc chắn –

Trả lời

5

Vì bạn đang lập kế hoạch để phân lớp UIControl, bạn chỉ có thể sử dụng

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; 

Sử dụng này, bất kỳ lớp có thể tự đăng ký làm mục tiêu cho bất kỳ sự kiện nào mà nó muốn trên bộ điều khiển tùy chỉnh của bạn.

13

Bạn có ý tưởng đúng. Dưới đây là cách tôi sẽ làm điều đó:

@interface TargetActionPair : NSObject 
{ 
    id target; 
    SEL action; 
} 
@property (assign) id target; 
@property (assign) SEL action; 
+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)selector; 
- (void)fire; 
@end 

@implementation TargetActionPair 
@synthesize target; 
@synthesize action; 

+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)anAction 
{ 
    TargetActionPair * newSelf = [[self alloc] init]; 
    [newSelf setTarget:aTarget]; 
    [newSelf setAction:anAction]; 
    return [newSelf autorelease]; 
} 

- (void)fire 
{ 
    [target performSelector:action]; 
} 

@end 

Với lớp tại chỗ, lưu trữ cặp mục tiêu/hành động của bạn là khá đơn giản:

MyCustomControl.h:

#import "TargetActionPair.h" 

@interface MyCustomControl : UIControl 
{ 
    NSMutableArray * touchUpEventHandlers; 
} 

- (id)init; 
- (void)dealloc; 

- (void)addHandlerForTouchUp:(TargetActionPair *)handler; 

@end 

MyCustomControl .m:

#import "TargetActionPair.h" 

@implementation MyCustomControl 

- (id)init 
{ 
    if ((self = [super init]) == nil) { return nil; } 
    touchUpEventHandlers = [[NSMutableArray alloc] initWithCapacity:0]; 
    return self; 
} 

- (void)dealloc 
{ 
    [touchUpEventHandlers release]; 
} 

- (void)addHandlerForTouchUp:(TargetActionPair *)handler 
{ 
    [touchUpEventHandlers addObject:handler]; 
} 

- (void) fireTargetsForTouchUpEvent 
{ 
    [touchUpEventHandlers makeObjectsPerformSelector:@selector(fire)]; 
} 

@end 
.210

Sau đó, thiết lập sự kiểm soát sẽ được thực hiện như sau:

[instanceOfMyControl addHandlerForTouchUp: 
     [TargetActionPair pairWithTarget:someController 
           andAction:@selector(touchUpEvent)]; 
+0

wow, câu trả lời lớn nhất mà tôi từng có ở đây;) cảm ơn! Đối với trường hợp của tôi, tôi đã tìm ra UIControl dường như đã cung cấp cho tôi những gì tôi cần. Nhưng khi có các sự kiện tùy chỉnh đặc biệt cần được xử lý, kỹ thuật của bạn thật tuyệt vời! –

+0

Thực ra, đối với các sự kiện tùy chỉnh, bạn có thể muốn sử dụng các bit UIControlEventApplicationReserved (16 có sẵn) và call - (void) sendActionsForControlEvents: (UIControlEvents) controlEvents; – Felixyz

+0

Điều thiếu sót ở đây là cách xóa mục tiêu/hành động và có thể là kiểm tra trùng lặp. – pixelfreak

38

Tôi chỉ muốn làm rõ những gì @Felixyz nói vì ban đầu tôi không rõ ràng.

Nếu bạn đang phân lớp UIControl, ngay cả khi bạn sắp có sự kiện tùy chỉnh, bạn không phải theo dõi các mục tiêu/hành động của riêng mình. Các chức năng đã có, tất cả các bạn phải làm là gọi mã dưới đây trong phân lớp của bạn để kích hoạt sự kiện:

[self sendActionsForControlEvents:UIControlEventValueChanged];

Sau đó, trong giao diện hoặc xem điều khiển mà instantiates tùy chỉnh của bạn UIControl, chỉ cần làm

[customControl addTarget:self action:@selector(whatever) forControlEvents:UIControlEventValueChanged];

đối với sự kiện tùy chỉnh, chỉ cần xác định enum riêng của bạn (ví dụ, UIControlEventValueChanged bằng 1 << 12). Chỉ cần đảm bảo phạm vi nằm trong phạm vi cho phép được xác định bởi UIControlEventApplicationReserved

+0

Đó là những gì tôi cần, cảm ơn –

Các vấn đề liên quan