How can I subclass a UITableView?

I want to subclass a UITableView as I want to create a reusable table view component in my application.

The idea is instead of using a delegate for say cellForRowAtIndexPath I want the table view itself to get that call.

  • Caching with AVPlayer and AVAssetExportSession
  • Xcode 6.4 “Could not download and install iOS 8.3 simulator”
  • UI Testing Failure - Neither element nor any descendant has keyboard focus on secureTextField
  • Interface orientation in iOS 6.0
  • swift class as parameter without .self
  • How to get all the images stored in the device and show them as gallery in iPhone sdk
  • I don’t think I want a UITableViewController as this UITableView that I want to build has to live in various UIViewControllers (and these UIViewController might have UITableViews of their own).

    I subclassed my UITableView as:

    @interface ShareUITableView : UITableView
    

    but none of its methods get called.

    My ShareUITableView is created via the NIB by setting the custom class to ShareUITableView. I have verified in code that a ShareUITableView is instantiated.

    My UITableView does not delegate to its view controller, so that’s not the problem.

    Any ideas?

    3 Solutions Collect From Internet About “How can I subclass a UITableView?”

    I think, you should still go with a Controller class. I expect subclassing UITableView to be tedious work — if possible with reasonable amount at all.

    There is no problem to have UIViewController/NoViewController implemented the delegate and datasource and yet assign another controller to a specific tableView. note, that the datasource and delegate don’t need to be subclasses of UITableViewController.

    have a look at this answer: Implement Delegate at Run Time?

    My UITableView does not delegate to its view controller, so that’s not the problem.

    You have to have to use delegate and datasource, that is how TableViews are filled and configured. otherwise you will have to overwrite every method of UITableView — including private ones, a no-go if you want into AppStore. Recreating UITableView without subclassing it would be even easier.

    If I understood you, you need this class declaration:

    @interface ShareUITableView : UITableView <UITableViewDataSource>
    

    And then, in your class constructor, you should assign the instance itself as its own datasource:

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

    Of course, the class will have to adopt the protocol.

    Good luck!

    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;
    }
    

    Subclassing is a great way to make reusable custom UI elements.