dev gr dev gr - 2 months ago 16
iOS Question

Override delegate and datasource setters in UICollectionView subclass

I created a subclass of

UICollectionView
and in that subclass I want to override setters of
dataSource
and
delegate
properties.

It uses another
segmentSelectionDelegate
and
segmentDataSource
properties (which can be set by caller) to populate the data. I want to disallow setting original dataSource and delegate properties by the caller because subclass itself is the dataSource and delegate.

How can I do that?

Below is what I did but it's throwing an error : Data source is not set.

Interface file:

@class ZISegmentCollectionView;

@protocol ZISegmentCollectionViewDelegate <NSObject>

-(void)segmentCollectionView:(ZISegmentCollectionView *)collectionView didSelectSegmentWithName:(NSString *)segmentName;

@end

@protocol ZISegmentCollectionViewDataSource <NSObject>

-(NSUInteger)segmentCollectionView:(ZISegmentCollectionView *)collectionView badgeCountForSegment:(NSString *)segmentName;
-(NSString *)segmentCollectionView:(ZISegmentCollectionView *)collectionView nameForSegmentAtIndexPath:(NSIndexPath *)indexPath;
-(NSUInteger)numberOfSegmentsInSegmentCollectionView:(ZISegmentCollectionView *)collectionView;

@end

@interface ZISegmentCollectionView : UICollectionView

@property(nonatomic, readonly) NSString * selectedSegmentName;
@property(nonatomic, weak) id<ZISegmentCollectionViewDelegate> segmentSelectionDelegate;
@property(nonatomic, weak) id<ZISegmentCollectionViewDataSource> segmentDataSource;

@end


I synthesised delegate and dataSource properties in
UICollectionView
subclass:

@synthesize dataSource = _dataSource;
@synthesize delegate = _delegate;


Wrote setters like:

-(void)setDataSource:(id<UICollectionViewDataSource>)dataSource
{
if (dataSource == self) {
_dataSource = dataSource;
}
}

-(void)setDelegate:(id<UICollectionViewDelegate>)delegate
{
if (delegate == self) {
_delegate = delegate;
}
}

Avi Avi
Answer

What you did by synthesizing the properties in your subclass is create new instance variables. When the superclass code checks if the data source is set, the answer is no, because its instance variable is still nil.

Drop the synthesize statements, because you will be implementing the setter anyway (and you don't need to provide a getter).

In your overriding setter, do nothing.

To set the actual data source, invoke [super setDatasource:self].

Comments