简体   繁体   中英

How to set the subclass of a TableView that was created programmatically? (no storyboards)

I am using a custom framework and I need to set the subclass of my 'TableView' and 'TableViewCell' to the custom framework. I would normally do this easily with the identity inspector but since I created everything programmatically, I do not know how to do it. I am also not using storyboards. Any tips?

---edit----

TableViewController.h

#import <UIKit/UIKit.h>
#import "Tasks.h"
#import "Properties2ViewController.h"
#import "PKRevealController.h"
#import "FMMoveTableView.h"
#import "FMMoveTableViewCell.h"
#import "DetailViewController.h"
@interface ToDoTableViewController : UITableViewController <Properties2ViewControllerDelegate, UITableViewDelegate, FMMoveTableViewDataSource>
@property (strong, nonatomic) NSMutableArray *taskArray;
-(IBAction)addCell:(id)sender;
@end

TableViewController.m

#import "ToDoTableViewController.h"

@implementation ToDoTableViewController
@synthesize taskArray;
- (id)init {
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
        UINavigationItem *i = [self navigationItem];
        [i setTitle:@"Task List"];
        [[i title] uppercaseString];
        UIBarButtonItem *bbi = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addCell:)];
        [[self navigationItem] setRightBarButtonItem:bbi];
        [self.tableView setSeparatorColor:[UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f]];
        [self.tableView setBackgroundView:nil];
        [self.tableView setBackgroundColor:[UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f]];
    }
    return self;
}
- (id) initWithStyle:(UITableViewStyle)style{
    return [self init];
}
-(void) viewDidLoad{
    FMMoveTableView *mtc = [[FMMoveTableView alloc]init];
    [mtc setDataSource:self];
    [self.tableView setDelegate:self];
    taskArray = [[NSMutableArray alloc] init];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (!cell)
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"UITableViewCell"];
    NSString *detailText = [NSString stringWithFormat:@"%.0f", [[taskArray objectAtIndex:[indexPath row]] timeInterval]];

    [[cell textLabel] setText:[[taskArray objectAtIndex:[indexPath row]] taskName]];
    cell.textLabel.text = [[[taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString];
    [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:15]];
    [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
    cell.textLabel.textColor = [UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f];

    [[cell detailTextLabel] setText:detailText];
    [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:16]];
    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [taskArray count];
}
-(IBAction)addCell:(id)sender{
    Properties2ViewController *pvc = [[Properties2ViewController alloc]init];
    [pvc setDelegate:self];
    [self presentViewController:pvc animated:YES completion:NULL];
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[self tableView] reloadData];
    }
-(void)properties2ViewControllerDidEnterPropertiesSuccesfully:(Tasks *)t{
    if (![[t taskName] isEqual: @""]) {
    [taskArray addObject:t];
    }
    [self.tableView reloadData];
}
-(void)moveTableView:(FMMoveTableView *)tableView moveRowFromIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{
    [tableView moveRowAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
    [tableView reloadData];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    Tasks *task = [taskArray objectAtIndex:[indexPath row]];
    DetailViewController *dvc = [[DetailViewController alloc]init];
    [dvc setTestTask:task];
    [[self navigationController] pushViewController:dvc animated:YES];
   // PKRevealController *pkrc = [[PKRevealController alloc]initWithFrontViewController:self rightViewController:dvc options:nil];
    //[pkrc showViewController:dvc animated:YES completion:NULL];

}
-(void)loadView{
    [super loadView];
}
@end

If you are instantiating the UITableView yourself, just instantiate the library class instead. For example, if you said this:

UITableView *tableView = [[UITableView alloc] initWithFrame:frame
    style: UITableViewStylePlain];

then do this instead:

LibraryTableView *tableView = [[LibraryTableView alloc] initWithFrame:frame
    style:UITableViewStylePlain];

If LibraryTableView provides some other, more specialized initWith… method, you may need to use that instead.

If you're storing a reference to the table view in a property or instance variable, you may also want to change the type of that property or instance variable from UITableView * to LibraryTableView * .

UPDATE

I believe if you're using a UITableViewController , you can create your own table view and assign it to the controller's tableView property:

UITableViewController *tvc = ...;
tvc.tableView = [[LibraryTableView alloc] initWithFrame:frame
    style:UITableViewStylePlain];

UPDATE 2

In your viewDidLoad , you're creating an FMMoveTableView , but you're not storing it in the view controller's tableView property. You must store it in the view controller's tableView property, and when you do, the view controller will automatically set the table view's dataSource and delegate to self .

-(void) viewDidLoad{
    self.tableView = [[FMMoveTableView alloc] init];
    taskArray = [[NSMutableArray alloc] init];
}

In your tableView:cellForRowAtIndexPath: , you need to instantiate an FMMoveTableViewCell , not a UITableViewCell . You send the alloc message to the class you want to instantiate:

- (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (!cell) {
        cell = [[FMMoveTableViewCell alloc]
            initWithStyle:UITableViewCellStyleValue1
            reuseIdentifier:@"Cell"];
    }

    // etc.

If you have your own custom subclass of FMMoveTableViewCell , instantiate that instead.

I have created custom TableViewCells before, you can create a custom class just like you would for viewControllers (File > New > File). When choosing which object to subclass, choose UITableViewCell.

Unfortunately, Xcode will not give you the option to include a .xib file, so you'll have to create one of those too: File > New > File, but this time on the left side of the window that pops up, select 'User Interface' instead of 'Cocoa Touch'. Choose the 'Empty' icon at this screen.

You will be asked whether the device family is iPhone or iPad. Since you are making a table view cell not a viewController, it doesn't matter which you pick.

When you create this object you will be presented with a blank canvas. Drag a 'Table View Cell' from the object library to the canvas and you're set to start creating!

It is of note that where you'd normally create outlets, you should create properties for TableViewCells. This is because other objects are going to be interacting with the TableViewCell, not just the TableViewCell's implementation file.

Here is what a header file for a custom TableViewCell might look like:

@interface MyCustomCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UIImageView *icon;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UILabel *number;

@end

My implementation file was empty.

However, that's not all. There is also some work to be done in the TableViewController that will utilize this cell. Be sure to import your TableViewCell's header file.

First, the cell has to be registered in the viewDidLoad method

// Resiter the Nib
UINib *nib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:@"MyCustomCell"];

And then when the TableViewController determines how to draw the cells:

- (UITableViewCell *) tableView:(UITableView *)tableView
      cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell"]

    // Then here you can set the properties of each cell
    [[cell label] setText:@"Some text here"];

    [[cell number] setText:[NSString stringWithFormat:@"%d", 5]];

    [[cell icon] setImage:[UIImage imageNamed:@"myImage]];
}

I hope this is helpful!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM