【问题标题】:Simple way to separate UITableview datasource and delegate from main UIViewController class?将 UITableview 数据源和委托与主 UIViewController 类分开的简单方法?
【发布时间】:2011-01-07 01:25:14
【问题描述】:

典型的 UITableView 使用模式是让主 UIViewController 成为目标数据源并委托它所持有的 UITableView。

是否有任何简单易学的教程可以帮助我弄清楚如何将与 UITableViewDelegate 和 UITableViewDataSource 方法相关的代码移动到一个单独的类中并将其挂接到我的 UIViewController 中?理想情况下,我希望委托和数据源都生活在同一个班级中。

现在,我正在通过 Interface Builder 创建 UITableView 并将其出口连接到我的控制器类。

典型代码:

@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

【问题讨论】:

标签: iphone objective-c xcode


【解决方案1】:

您可以创建单独的类(使用 UITableViewDelegate、UITableViewDataSource)并将它们作为外部文件添加到 IB 中并链接 IBActions

【讨论】:

  • 我在 MyController 中有实现 UITableViewDelegate、UITableViewDataSource 的单独类。您如何将这些实例链接为 IBAction?
【解决方案2】:

在 IB 中,您可以将“外部对象”从 Library->Cocoa Touch->Controllers 拖到您的 xib 窗口中。然后,您可以选择该对象、查看检查器并设置类。它现在可以用作委托等。

【讨论】:

  • IB 是否负责这个类的实例化?我需要做什么才能使用它吗?我试过这个,但我的应用程序似乎由于“EXC_BAD_ACCESS”而崩溃。
  • 是的,你是对的。现在我得到了同样的东西,我可以测试它。我通过拖动对象而不是外部对象来重做此操作。接下来,我在 File's Owner 控制器中声明了一个类型为 Object 项类型的 IBOutlet。然后,我将目标新控件的委托链接到新对象,将新对象的视图链接到新控件,将新 IBOutlet 链接到新对象……然后它就运行了!
  • 仅供参考,IBOutlet 的原因是新控件需要在实例化后保留。如果你不这样做,它会立即被销毁,基本上你会得到一个空指针异常。
  • 这是一种可能,但如果你只是用它来设置一个委托和数据源出口到一个单独的对象,你最好在代码中这样做,这样每个人都可以很容易地看到你是什么取决于。此外,如果您需要传递任何数据,您将创建一个从该代理到主控制器的出口。您不妨新建对象并显式声明委托和数据源分配以供所有人查看。所以,简而言之,我认为这是一个糟糕的解决方案,尽管完全有可能。
【解决方案3】:

我花了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

【讨论】:

    【解决方案4】:

    第一 事情是,如果您使用 UITableViewController 子类和接口构建器,您将需要断开已默认连接的委托和数据源出口。 (提示,查看连接检查器)。检查即使您在 viewController 中有一个 tableView。

    第二创建您的类并确保它们符合&lt;UITableViewDelegate&gt;&lt;UITableViewDataSource&gt;。如果您使用 objc,您可能必须在 .h 文件中声明此合同。

    第三,在您的视图控制器中实例化此类或两​​个单独的类,例如viewDidLoad,然后分配self.tableView.delegate = myCustomDelegateInstanceself.tableView.dataSource = myCustomDataSourceInstance

    现在,通过控制器的任何调用都将被分派到您的自定义处理程序。很基本。

    真正这样做的唯一原因是,如果您 1) 有一个非常臃肿的控制器,或者 2) 您需要在其他地方重用 dataSource 和委托方法,并且您希望避免代码重复。否则,最好将其保留。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2012-07-01
      • 2016-07-27
      • 1970-01-01
      相关资源
      最近更新 更多