我怎样才能将UITableView子类化?

时间:2012-02-04 20:11:57

标签: ios objective-c uitableview cocoa-touch

我想继承一个UITableView,因为我想在我的应用程序中创建一个可重用的表视图组件。

我的想法是使用委托来代替说cellForRowAtIndexPath我希望表视图本身能够获得该调用。

我认为我不想要一个UITableViewController,因为我要构建的UITableView必须存在于各种UIViewControllers中(并且这些UIViewController可能有自己的UITableViews。)

我将UITableView子类化为:

@interface ShareUITableView : UITableView

但是没有一个方法被调用。

通过将自定义类设置为ShareUITableView,可以通过NIB创建我的ShareUITableView。我已经在代码中验证了ShareUITableView的实例化。

我的UITableView没有委托给它的视图控制器,所以这不是问题。

有什么想法吗?

3 个答案:

答案 0 :(得分:7)

如果我理解你,你需要这个类声明:

@interface ShareUITableView : UITableView <UITableViewDataSource>

然后,在类构造函数中,您应该将实例本身分配为自己的数据源:

- (id)init
{
    //...
    self.dataSource = self;
    //...
}

当然,课程必须采用该协议。

祝你好运!

答案 1 :(得分:5)

MyTableView.h

// MyTableView.h

// This overrides the UITableViewDataSource with your own so you can add any methods   you would like.
@protocol MyTableViewDataSource <UITableViewDataSource>

@required
// This is where you put methods that are required for your custom table to work (optional)
- (int)myRequiredMethod;

@optional
// This is where you put methods that are optional, like settings (optional)

@end

// This overrides the UITableViewDelegate with your own so you can add any methods you would like.
@protocol MyTableViewDelegate <UITableViewDelegate>

@required
// This is where you put methods that are required for your custom table to work (optional)

@optional
// This is where you put methods that are optional, like settings (optional)

@end

// Make sure you add UITableViewDelegate and UITableViewDataSource implementations.
@interface MyTableView : UITableView <UITableViewDelegate, UITableViewDataSource> {

    // Your customer datasource and delegate.
    id <MyTableViewDataSource> myDataSource;
    id <MyTableViewDelegate> myDelegate;
}

@end

MyTableView.m

// MyTableView.m

#import "MyTableView.h"

@implementation MyTableView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code

        // This is how you can use your custom method.
        int i = [myDataSource myRequiredMethod];
    }
    return self;
}

- (void)awakeFromNib {
    // This assigns the delegate and datasource you assigned to File's Owner in your xib to your custom methods
    myDataSource = (id<MyTableViewDataSource>)self.dataSource;
    myDelegate = (id<MyTableViewDelegate>)self.delegate;
    self.delegate = self;
    self.dataSource = self;
}

// This is an example of how to override an existing UITableView method.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // This calls the method implemented in your ViewController. See Below.
    NSInteger rows = [myDataSource tableView:tableView numberOfRowsInSection:section];

    return rows;
}

@end

MyViewController.h

// MyViewController.h

#import "MyTableView.h"

// Use MyTableViewDataSource and MyTableViewDelegate instead of UITableViewDataSource and UITableViewDelegate
@interface MyViewController : UIViewController <MyTableViewDataSource, MyTableViewDelegate> {

@end

MyViewController.m

// MyViewController.m

#import "MyViewController.h"

@interface MyViewController ()

@end

@implementation MyViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

// This method will be overridden by myTableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (int)myRequiredMethod {
    return 2;
}

子类化是制作可重复使用的自定义UI元素的好方法。

答案 2 :(得分:2)

我认为,你仍然应该使用Controller类。我希望将UITableView子类化为繁琐的工作 - 如果可能的话,可以使用合理的数量。

让UIViewController / NoViewController实现委托和数据源并将另一个控制器分配给特定的tableView是没有问题的。请注意,数据源和委托不需要是UITableViewController的子类。

看一下这个答案:Implement Delegate at Run Time?

  

我的UITableView没有委托给它的视图控制器,所以这不是问题。

您必须使用委托和数据源,这就是填充和配置TableView的方式。否则你将不得不覆盖UITableView的每个方法 - 包括私有方法,如果你想要进入AppStore则不会。重新创建UITableView而不进行子类化会更容易。