2012-01-25 39 views
15

Tôi có một số UIScrollView mà tôi cần phải phân lớp và trong lớp con tôi cần đính kèm UIScrollViewDelegate để tôi có thể triển khai phương thức viewForZoomingInScrollView.Nhiều đại biểu cho một đối tượng?

Sau đó, tôi có một UIViewController nơi tôi cần phải nhanh chóng một đối tượng của lớp con UIScrollView này mà tôi tạo ra, và tôi cũng muốn làm cho UIViewController một UIScrollViewDelegate cho đối tượng này để tôi có thể thực hiện scrollViewDidZoom trong lớp UIViewController này.

Làm cách nào để có thể tạo một đối tượng có hai đại biểu? (Tôi biết tôi có thể dễ dàng chỉ có một đại biểu và chỉ thực hiện cả hai phương pháp ở đó, nhưng với mục đích thiết kế tôi muốn làm điều đó theo cách mà tôi đang đề cập đến).

+0

Tại sao bạn làm điều này? Tại sao bạn không thể truyền một thông điệp từ customScrollView đến VC của bạn có SV (với một đại biểu thứ hai (tùy chỉnh))? –

+0

Có lẽ đó là những gì tôi cần làm, vì vậy nếu tôi thực hiện scrollViewDidZoom trong lớp con SV của tôi, làm thế nào tôi có thể gửi cho tôi một tin nhắn VC bất cứ khi nào nó được kích hoạt? @totumus maximus –

+0

Bạn sẽ phải thực hiện một đại biểu tùy chỉnh (giao thức) trong chế độ xem tùy chỉnh ur và làm cho đại biểu VC của bạn về nó. Tại thời điểm các đại biểu scrollview của bạn được gọi là bạn cũng gọi một trong các phương thức đại biểu tùy chỉnh trong đại biểu tùy chỉnh của bạn. Bằng cách này scrollview giữ trách nhiệm của chính nó và xem cha mẹ của bạn được phản ứng trên chức năng di chuyển cụ thể. Tôi sẽ đưa nó vào câu trả lời cho yah. –

Trả lời

7

Bạn không muốn đối tượng có 2 đại biểu. Bạn muốn giữ customScrollView giữ nguyên trách nhiệm của các hàm UIScrollViewDelegate riêng của nó.

Để làm cho cha mẹ của bạnVC phản hồi các phương thức ủy nhiệm của UIScrollView, bạn sẽ phải thực hiện một đại biểu tùy chỉnh bên trong customScrollView của mình.

Hiện tại, chức năng UIScrollViewDelegate được gọi là bạn cũng sẽ gọi một trong các chức năng đại biểu của bạn từ đại biểu tùy chỉnh của bạn. Bằng cách này, phụ huynh của bạn sẽ phản hồi tại thời điểm bạn muốn.

Nó sẽ giống như thế này.

CustomScrollView.h

@protocol CustomDelegate <NSObject> 

//custom delegate methods 
-(void)myCustomDelegateMethod; 

@end 

@interface CustomScrollView : UIScrollView <UIScrollViewDelegate> 
{ 
    id<CustomDelegate> delegate 
    //the rest of the stuff 

CustomScrollView.m

-(void) viewForZoomingInScrollView 
{ 
    [self.delegate myCustomDelegateMethod]; 
    //rest of viewForZoomingInScrollView code 

ParentVC.h

@interface CustomScrollView : UIViewController <CustomDelegate> 
{ 
    //stuff 

ParentVC.m

-(void)makeCustomScrollView 
{ 
    CustomScrollView *csv = [[CustomScrollView alloc] init]; 
    csv.delegate = self; 
    //other stuff 

} 

-(void)myCustomDelegateMethod 
{ 
    //respond to viewForZoomingInScrollView 
} 

Tôi hy vọng điều này bao gồm đầy đủ vấn đề của bạn. Chúc may mắn.

+0

Cảm ơn bạn đã viết lên. –

+0

Luôn sẵn sàng giúp đỡ ^^ –

+2

@TotumusMaximus một ScrollView đã có một thuộc tính có tên là "đại biểu", ở đây bạn cố gắng khai báo một thuộc tính có cùng tên, là BAD – onmyway133

2

Tôi không nghĩ rằng bạn có thể có hai đại diện UIScrollViewDelegate được kết nối trực tiếp với cùng một đối tượng.

Điều bạn có thể làm là yêu cầu hai đại biểu được kết nối với chuỗi. Tức là, bạn kết nối một đại biểu với người khác, sau đó có các thông điệp chuyển tiếp trước đó đến sau khi nó không thể xử lý chúng trực tiếp.

Trong mọi trường hợp, tôi nghĩ rằng tôi thiếu một chút để đề xuất đầy đủ giải pháp, cụ thể là lý do tại sao bạn cần một đại biểu thứ hai và không thể thực hiện luôn thông qua một đại biểu duy nhất. Nói cách khác, những gì tôi nghĩ là có thể có các thiết kế thay thế mà sẽ tránh cần hai đại biểu.

3

Câu trả lời ngắn gọn: bạn không thích. Các đại biểu là thường là một yếu one-to-one mối quan hệ:

@property (nonatomic, weak /*or assign*/) id<MyViewDelegate> delegate; 

Đôi khi bạn sẽ thấy một "người nghe" mẫu thiết kế, đó là hình thức một-nhiều của các đại biểu:

- (void) addListener:(id<MyViewListener>)listener; 
- (void) removeListener:(id<MyViewListener>)listener; 

Trong trường hợp của bạn, có vẻ như không phải là một điểm ghi đè công khai tốt đẹp trong UIScrollView cho phép các lớp con chỉ định viewForZoomingInScrollView. Tôi sẽ tránh làm cho UIScrollView trở thành đại diện của mình, nếu có thể. Bạn có thể làm cho UIViewController UIScrollViewDelegate và có nó cung cấp viewForZooming. Hoặc bạn có thể tạo một lớp con xem trung gian sử dụng UIScrollView, cung cấp viewForZooming và chuyển tiếp các phương thức đại biểu khác lên.

12

Thỉnh thoảng bạn nên đính kèm một số đại biểu vào chế độ xem cuộn. Trong trường hợp đó, bạn có thể xây dựng một splitter đoàn đơn giản:

// Public interface 
@interface CCDelegateSplitter : NSObject 

- (void) addDelegate: (id) delegate; 
- (void) addDelegates: (NSArray*) delegates; 

@end 

// Private interface 
@interface CCDelegateSplitter() 
@property(strong) NSMutableSet *delegates; 
@end 

@implementation CCDelegateSplitter 

- (id) init 
{ 
    self = [super init]; 
    _delegates = [NSMutableSet set]; 
    return self; 
} 

- (void) addDelegate: (id) delegate 
{ 
    [_delegates addObject:delegate]; 
} 

- (void) addDelegates: (NSArray*) delegates 
{ 
    [_delegates addObjectsFromArray:delegates]; 
} 

- (void) forwardInvocation: (NSInvocation*) invocation 
{ 
    for (id delegate in _delegates) { 
     [invocation invokeWithTarget:delegate]; 
    } 
} 

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector 
{ 
    NSMethodSignature *our = [super methodSignatureForSelector:selector]; 
    NSMethodSignature *delegated = [(NSObject *)[_delegates anyObject] methodSignatureForSelector:selector]; 
    return our ? our : delegated; 
} 

- (BOOL) respondsToSelector: (SEL) selector 
{ 
    return [[_delegates anyObject] respondsToSelector:selector]; 
} 

@end 

Sau đó chỉ cần thiết lập một thể hiện của splitter này như một đại biểu của xem di chuyển và đính kèm bất kỳ số lượng đại biểu dự splitter. Tất cả họ sẽ nhận được các sự kiện của đoàn. Một số cảnh báo áp dụng, ví dụ như tất cả các đại biểu được giả định là cùng loại, nếu không bạn sẽ gặp rắc rối với việc triển khai thực hiện respondsToSelector ngây thơ. Đây không phải là vấn đề lớn, thật dễ dàng để thay đổi việc triển khai để chỉ gửi các sự kiện ủy quyền tới những người hỗ trợ họ.

+0

nếu nó được khai báo như @property (gán) CCDelegateSplitter * đại biểu? –

+2

thay vì [NSMutableSet set]; sử dụng [NSHashTable hashTableWithOptions: NSPointerFunctionsWeakMemory]; vì nó sẽ giữ một tham chiếu yếu cho các đối tượng đại biểu và sẽ tránh chu kỳ giữ lại cho chúng – Nav

+0

Không sử dụng giải pháp này, các đại biểu không thể được deallocated do tham chiếu. Sử dụng những gì Nav đề xuất, NSNotification, hoặc cái gì khác. Chỉ cần không phải ... –

0

Dưới đây là một giải pháp thanh lịch liên quan đến 2 đại biểu:

  • Tuỳ chỉnh xem cuộn lớp LTInfiniteScrollView lớp con UIView (không UIScrollView) và thêm một UIScrollView như một đứa trẻ. LTInfiniteScrollView tự đặt làm đại biểu của số UIScrollView này.

  • LTInfiniteScrollView xác định thuộc tính delegate của riêng nó và giao thức. Vì LTInfiniteScrollView không phân loại UIScrollView, không có thuộc tính hiện tại delegate nào xung đột.

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