Простой способ отделить источник данных UITableview и делегировать от основного класса UIViewController? - PullRequest
9 голосов
/ 20 января 2010

Типичный шаблон использования UITableView состоит в том, чтобы основной UIViewController стал целевым источником данных и делегировал для UITableView, к которому он привязан.

Существуют ли какие-либо простые и легкие для изучения руководства, которые помогли бы мне выяснить, как переместить код, относящийся к методам UITableViewDelegate и UITableViewDataSource, в отдельный класс и вместо этого подключить его к моему UIViewController? В идеале я хотел бы, чтобы и делегат, и источник данных жили в одном классе.

Сейчас я создаю UITableView с помощью Interface Builder и подключаю его выход к классу моего контроллера.

Типичный код:

@interface MyController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
    IBOutlet UITableview *myTableview;
}

Я хочу сделать что-то вроде этого:

@interface MyController : UIViewController 
{
    IBOutlet UITableview *myTableview;
}
@end

@interface MyTableSourceDelegate : NSObject<UITableViewDelegate, UITableViewDataSource>
{
}

@implementation MyTableSourceDelegate
    // implement all of the UITableViewDelegate and methods in this class 
@end

Ответы [ 4 ]

3 голосов
/ 06 января 2012

Я трачу 2 часа, чтобы решить эту проблему:

Это работает для меня

//  GenreDataSource.h

#import Foundation/Foundation.h

    @interface GenreDataSource : NSObject <UITableViewDataSource> {
        NSArray *dataSource;
        CGSize cellSize;
    }

@property(nonatomic, assign) CGSize cellSize;

@end



//  GenreDataSource.m
#import "GenreDataSource.h"

@implementation GenreDataSource
@synthesize cellSize;

-(id)init{

    self = [super init];
    if ( self != nil ) {

        dataSource = [[NSArray alloc] initWithObjects:@"All",@"Folk",@"Disco",@"Blues",@"Rock",@"Dance",@"Hip-Hop",@"R&B",@"Soul",@"Lounge",@"Techno",@"Bubstep", nil];
    }
    return self;
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [dataSource count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"CellPicker";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
        [cell setSelectionStyle:UITableViewCellSelectionStyleGray];

        //сконфигурируем структуру
        FontLabel *fLabel= [[FontLabel alloc] initWithFrame:CGRectMake(30, 
                                                                       5, 
                                                                       cellSize.width-30, 
                                                                       cellSize.height-5)
                                                   fontName:@"HelveticaNeueCondensedBlack" 
                                                  pointSize:18.0f];
        [fLabel setTextColor:[UIColor darkTextColor]];
        [fLabel setTag:101];
        [fLabel setBackgroundColor:[UIColor clearColor]];
        [cell.contentView addSubview:fLabel];
        [fLabel release];
    }

    FontLabel *fLabel = (FontLabel*)[cell viewWithTag:101];
    [fLabel setText:[dataSource objectAtIndex:indexPath.row]];

    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

@end
2 голосов
/ 21 апреля 2015

Первое : если вы используете подкласс UITableViewController со сборщиком интерфейса, вы захотите отключить выходы делегата и источника данных, которые уже подключены по умолчанию. (Подсказка, посмотрите в инспекторе соединений). Проверьте, даже если у вас есть tableView внутри viewController.

Второй создайте свои классы и убедитесь, что они соответствуют <UITableViewDelegate> и <UITableViewDataSource>. Возможно, вам придется объявить этот контракт в файле .h, если вы используете objc.

Третий , В вашем контроллере представления создайте экземпляр этого класса или двух отдельных классов где-то вроде viewDidLoad, а затем присвойте self.tableView.delegate = myCustomDelegateInstance и self.tableView.dataSource = myCustomDataSourceInstance.

Теперь любые вызовы, поступающие через контроллер, будут отправляться вашим пользовательским обработчикам. Довольно простой.

Единственная причина, чтобы действительно сделать это, если у вас 1) очень раздутый контроллер или 2) вам нужно повторно использовать dataSource и делегировать методы где-то еще, и вы хотите избежать повторения кода. В противном случае, возможно, лучше оставить это на месте.

0 голосов
/ 20 января 2010

В IB вы можете перетащить «Внешний объект» из Библиотеки-> Касание Какао-> Контроллеры в окно XIB.Затем вы можете выбрать этот объект, просмотреть инспектор и установить класс.Теперь он может быть делегатом и т. Д.

0 голосов
/ 20 января 2010

Вы можете создавать отдельные классы (с UITableViewDelegate, UITableViewDataSource) и добавлять их в IB как внешние файлы и связывать IBActions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...