Класс, написанный с initWithFrame - я хочу создать экземпляр из раскадровки

Я хочу использовать UIExpandableTableView - https://github.com/OliverLetterer/UIExpandableTableView.

Я столкнулся с проблемой, потому что это только инициализатор initWithFrame:

#pragma mark - Initialization

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
    if ((self = [super initWithFrame:frame style:style])) {
        self.maximumRowCountToStillUseAnimationWhileExpanding = NSIntegerMax;
        self.expandableSectionsDictionary = [NSMutableDictionary dictionary];
        self.showingSectionsDictionary = [NSMutableDictionary dictionary];
        self.downloadingSectionsDictionary = [NSMutableDictionary dictionary];
        self.animatingSectionsDictionary = [NSMutableDictionary dictionary];
    }
    return self;
}

Я пытался инициализировать tableView из раскадровки и понял, что я вижу ошибки, потому что это initWithFrame никогда не вызывается и NSMutableDictionaries не инициализируются. Как это решить?

Если это не легко решить, я могу просто создать программный экземпляр и пойти с initWithFrameНо помимо желания использовать раскадровку, мне также любопытно, каким будет решение.


РЕДАКТИРОВАТЬ Вот как эти свойства и их ивары объявляются в UIExpandableTableView. Это в.h файле:

@interface UIExpandableTableView : UITableView <UITableViewDelegate, UITableViewDataSource, NSCoding> {

@private id __UIExpandableTableView_weak _myDelegate; id __UIExpandableTableView_weak _myDataSource;

NSMutableDictionary *_expandableSectionsDictionary;     // will store BOOLs for each section that is expandable
NSMutableDictionary *_showingSectionsDictionary;        // will store BOOLs for the sections state (nil: not expanded, 1: expanded)
NSMutableDictionary *_downloadingSectionsDictionary;    // will store BOOLs for the sections state (nil: not downloading, YES: downloading)
NSMutableDictionary *_animatingSectionsDictionary;

NSInteger _maximumRowCountToStillUseAnimationWhileExpanding;

BOOL _onlyDisplayHeaderAndFooterViewIfTableViewIsNotEmpty;
UIView *_storedTableHeaderView;
UIView *_storedTableFooterView;

}

Вот вершина.m файла UIExpandableTableView. T

@interface UIExpandableTableView ()

@property (nonatomic, retain) NSMutableDictionary *expandableSectionsDictionary;
@property (nonatomic, retain) NSMutableDictionary *showingSectionsDictionary;
@property (nonatomic, retain) NSMutableDictionary *downloadingSectionsDictionary;
@property (nonatomic, retain) NSMutableDictionary *animatingSectionsDictionary;

@property (nonatomic, retain) UIView *storedTableHeaderView;
@property (nonatomic, retain) UIView *storedTableFooterView;

- (void)downloadDataInSection:(NSInteger)section;

- (void)_resetExpansionStates;

@end

4 ответа

Вы можете создать подкласс из UIExpandableTableView и сделать

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
    if (self = [super initWithFrame:frame style:style]) {
        [self configure];
    }
    return self;
}


-(id)initWithCoder:(NSCoder *)aCoder {
    if(self = [super initWithCoder:aCoder]){ 
        [self configure];
    }
   return self;
}


-(void) configure {
    self.maximumRowCountToStillUseAnimationWhileExpanding = NSIntegerMax;
    self.expandableSectionsDictionary = [NSMutableDictionary dictionary];
    self.showingSectionsDictionary = [NSMutableDictionary dictionary];
    self.downloadingSectionsDictionary = [NSMutableDictionary dictionary];
    self.animatingSectionsDictionary = [NSMutableDictionary dictionary];
}

Nibs и Storybord создаются через initWithCoder:

Subcalssing позволяет использовать сторонний код, не исправленный в этом случае.

Все, что вам нужно сделать, это удалить initWithFrame: и переопределить initWithCoder: вместо. Этот метод вызывается, когда элемент конструктора интерфейса достигает init, чтобы позволить вам настроить свои словари. И не беспокойтесь об устранении аргументов стиля и фрейма, потому что оба этих случая будут обрабатываться из конструктора интерфейса.

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        NSLog(@"%s",__PRETTY_FUNCTION__); // Proof of call
        self.maximumRowCountToStillUseAnimationWhileExpanding = NSIntegerMax;
        self.expandableSectionsDictionary = [NSMutableDictionary dictionary];
        self.showingSectionsDictionary = [NSMutableDictionary dictionary];
        self.downloadingSectionsDictionary = [NSMutableDictionary dictionary];
        self.animatingSectionsDictionary = [NSMutableDictionary dictionary];
    }
    return self;
}

Я бы сделал следующее:

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
    if ((self = [super initWithFrame:frame style:style])) {
        [self setup];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self setup];
}

- (void)setup {
    self.maximumRowCountToStillUseAnimationWhileExpanding = NSIntegerMax;
    self.expandableSectionsDictionary = [NSMutableDictionary dictionary];
    self.showingSectionsDictionary = [NSMutableDictionary dictionary];
    self.downloadingSectionsDictionary = [NSMutableDictionary dictionary];
    self.animatingSectionsDictionary = [NSMutableDictionary dictionary];
}

Я думаю, что это самое простое решение... вам не нужно беспокоиться о том, как инициализируется контроллер представления.

-(void)viewDidLoad
{
    [super viewDidLoad];
    self.maximumRowCountToStillUseAnimationWhileExpanding = NSIntegerMax;
    self.expandableSectionsDictionary = [NSMutableDictionary dictionary];
    self.showingSectionsDictionary = [NSMutableDictionary dictionary];
    self.downloadingSectionsDictionary = [NSMutableDictionary dictionary];
    self.animatingSectionsDictionary = [NSMutableDictionary dictionary];
}
Другие вопросы по тегам