Are there Anyone that use TableViewController without subclassing? - iphone

I am just curious. In IB, we can put a tableviewcontroller. However, as far as I know, we always subclass that tableview controller right? That way we can implement delegate, etc.
However, it seems that for some "default" behavior, IPhone intended tableviewcontroller to be used as is. Otherwise, why would IB let us put tableViewController like that?
Are there any sample code where people use tableViewController without subclassing?
Where does they implement things like what cells to draw, etc. then?
I guess the right answer of the question is that it's simply ridiculous to use a UITableViewController without sub classing. No body is doing it. Please correct me if I am wrong. I am just curious.

Whether you use a subclass of UITableViewController or UIViewController you need to set the data your table is going to display, otherwise, what's the point of a blank table? To achieve that you have to subclass and implement some methods. It's also a good idea to keep the delegate and the datasource in the same controller, unless the complexity really asks for different classes.
That being said, I always create my own table controllers as a subclass of UIViewController and implement the table controllers methods myself, because it gives you more flexibility. Matt Gallagher has several posts on how and why. See UITableView construction, drawing and management (revisited).
If you want to give it a try, create a subclass of UIViewController with a XIB and add the following sample code:
// interface
#import <UIKit/UIKit.h>
#interface SettingsVC : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *array;
#end
// implementation
#synthesize tableView = _tableView;
#synthesize array = _array;
# pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.array count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int row = [indexPath row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [self.array objectAtIndex:row];
return cell;
}
Then add a UITableView object to the XIB, link the tableView of the controller to the UITableView object, and link the delegate and datasource of the UITableView to the controller.

No, this is not necessary to inherit your class with tableViewController. You can use table view by simply
putting TableViewController in xib.
and setting its delegate and datasourse to file's owner you can draw the table cells.

I don't think you can use a UITableViewController as is, it's like using a UIViewController without subclassing it : you can't set any inner mechanics.
But you can have a UITableView without using a UITableViewController.

Sure you can use UITableViewController without subclassing it.
Samplecode is very easy and straight forward.
For example like this:
- (IBAction)selectSomeOption:(id)sender {
UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
tableViewController.tableView.dataSource = self;
tableViewController.tableView.delegate = self;
tableViewController.title = "Select some option";
[self.navigationController pushViewController:tableViewController animated:YES];
}
and the UITableViewDatasource and Delegate methods go into the same class.
Sure, if you like pain you could create a UIViewController in code and add a tableView on your own.
Or create a subclass for such an easy task.
The use of a non subclassed UITableViewController is sometimes convenient.

Related

iOS 7 UITableView indexpath row property is nil

I have a UITableView and it contains a custom UITableViewCell. To test, I have an array that has three strings in it. The UITableView delegate methods are called as expected, however, the tableView:cellForRowAtIndexPath delegate is always passed an NSIndexPath instance whose row property is always == nil:
tableView:cellForRowAtIndexPath is called 3 times (once for each object in my array). I added the tableView from within the designer (storyboard) and created an outlet for it. The UITableViewCell instances appear to be correctly instantiated which each call to this delegate. I just can't wrap my head around why the [indexPath row] value is always nil.
Interface(s):
In the implmentation file:
#interface FirstViewController ()
#property(nonatomic, strong)AppDelegate *sharedDelegate;
#property(nonatomic, strong)NSArray *userList;
#end
In the header:
#interface FirstViewController : UITableViewController <FacebookDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#end
Init the custom cell:
-(void)viewDidLoad
{
[self.tableView registerClass: [ListCategoryCell class]forCellReuseIdentifier:#"ListCategoryCell"];
self.userList = #[#"d", #"g", #"f"]; // make some test data
}
And the delegate this is driving me mad:
//NSIndexPath.row is nil ?!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"ListCategoryCell";
ListCategoryCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = (ListCategoryCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
cell.titleLabel.text = [self.userList objectAtIndex:[indexPath row]];
cell.detailLabel.text = #"Detail";
return cell;
}
Am I missing something? Thanks!
Working Now
I left out some context (and I should not have) that I believe was very relevant to my problem. I created a UIViewController originally and then added a UITableView to this as the view. In the UITableView I created a custom prototype cell. I did all the house work:
UIViewController implemented the UITableViewDelegate & UITableViewDatasource.
Created and outlet for the UITableView.
Hooked up all the outlets
Everything seemed to work except for the fact that indextPath.row property was always nil. Some resources I found suggested that custom cells were not visible before the uitableview delegates were called.
In the end I made my class a subclass of UITableViewController. Things started working. I am still curious why my original attempt was failing.
Thanks for everyone's time. Some great comments helped me investigate some topics that are "good to know".
You need to provide at least two methods in view controller if you want it to manage your table view. They are:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You've already provided the second, so your table view actually can produce cells but it doesn't know how many.The default value the first method returns is nil.That is the reason why you don't even have an index path.
Optionally:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
The default value is one,so you don't need to override this in case you have only one section
Make sure your view controller also follows delegate and datasource protocols.

Passing data between UITableViewCell and UITableViewController?

I created master details template project in xcode 4.6 and I added custom cell with 2 textfields. I also created new class which is subclass of UITableViewCell and inside this class I created outlets for text fields. When user types something NSMutableArray is updated and this works fine. Now I am wondering how to pass this array back to MasterViewController (UITableViewController) so that I can use this data to show calculations.
I tried using tutorials for delegates between UIViewControllers but I keep getting errors. Any help is appreciated.
You shouldn't keep data inside the UITableViewCell, as it breaks the MVC.
You need to get a reference of the UITextField on your cell. This is how I do in a login form:
I have a custom cell subclass called TextFieldCell, it has an outlet called textField, I want that my UITableViewController have references to these UITextFields.
First I open my storyboard, set the cell class to TextFieldCell and than connect the UITextField to cell textField outlet. Than I add this to the tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
(…)
if (indexPath.row == 0) {
// Sets the textField of the first cell as the loginTextField.
self.loginTextField = tCell.textField;
} else {
// Sets the textField of the second cell as the passwordTextField.
self.passwordTextField = tCell.textField;
}
tCell.textField.delegate = self;
(…)
}
Now I can access the value of my loginTextField and my passwordTextField. I do that on the tableView:cellForRowAtIndexPath: because that's when I'm creating the cell to add to the table view.
In your case you need to create Protocol:
I just Give Basic Idea for how to Create Protocol
Also Read This Question
#DetailViewController.h
#import <UIKit/UIKit.h>
#protocol MasterDelegate <NSObject>
-(void) getButtonTitile:(NSString *)btnTitle;
#end
#interface DetailViewController : MasterViewController
#property (nonatomic, assign) id<MasterDelegate> customDelegate;
#DetailViewController.m
if([self.customDelegate respondsToSelector:#selector(getButtonTitile:)])
{
[self.customDelegate getButtonTitile:button.currentTitle];
}
#MasterViewController.m
create obj of DetailViewController
DetailViewController *obj = [[DetailViewController alloc] init];
obj.customDelegate = self;
[self.navigationController pushViewController:reportTypeVC animated:YES];
and add delegate method in MasterViewController.m for get button title.
#pragma mark -
#pragma mark - Custom Delegate Method
-(void) getButtonTitile:(NSString *)btnTitle;
{
NSLog(#"%#", btnTitle);
}

Objective-C: Problems accessing objects in other UIViewControllers

So I have a Custom UITableViewCell that holds a reference to its containing view controller (the VC that has its table in it).
// MyCell.h
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#interface MyCell : UITableViewCell
#property (nonatomic, strong) IBOutlet RootViewController *rootViewController;
-(IBAction)checkBoxClicked:(UIButton*)sender;
// MyCell.m
#implementation MyCell
#synthesize rootViewController = _rootViewController;
-(IBAction)checkBoxClicked:(UIButton*)sender
{
[self setCheckBoxChecked:!_checkBoxChecked];
[_rootViewController refreshVisibleViewForCellTagged:self.tag];
}
In my cell I have a button that changes a variable and then calls a function in my rootViewController. The method is actually called however when I try to access any object in the RootViewController inside of the refreshVisibleViewForCellTagged method they are are '0x0' / nil;
// RootViewController.h
#interface RootViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *myTableView;
// RootViewController.m
- (void) refreshVisibleViewForCellTagged:(NSInteger)cellTag
{
UITableView *tableView = self.myTableView; // nil
NSIndexPath *indexPath = [self.myTableView indexPathForSelectedRow]; // nil
MyCell *selectedCell = (MyCell*)[self.myTableView cellForRowAtIndexPath:indexPath]; // nil
if (selectedCell.tag == cellTag) {
NSLog(#"Refresh one way.");
} else {
NSLog(#"Do something else.");
}
}
Can anyone shed some light as to why I cant access any objects/variables in the RootController from within the method 'refreshVisibleViewForCellTagged'?
Please and thank you!
** My big question is Why can't I access any objects when calling a method in a view controller From a different view controller. There is some great programming truth that I am not aware of here, is it a permissions issue? Im not using #class (forward classing) in this instance.
As #trojanfoe said, delegation is a better way to do it.
Instead of #import "RootViewController.h", it is better to adop delegation. Because UITableViewCell is a child and RootViewController is the parent view. You don't want the child to talk directly with the parent.
To adopt delegation:
in MyCell.h file
remove #import "RootViewController.h".
revise MyCell.h as follows:
#protocol MyCellDelegate; // if you need to have forward declaration
#interface MyCell : UITableViewCell
// #property (nonatomic, strong) IBOutlet RootViewController *rootViewController;
#property (nonatomic) id <MyCellDelegate> delegate;
#end
#protocol MyCellDelegate <NSObject>
- (void)refreshVisibleViewForCellTagged:(NSInteger)cellTag;
#end
in MyCell.m.
#synthesize delegate;
-(IBAction)checkBoxClicked:(UIButton*)sender {
[self setCheckBoxChecked:!_checkBoxChecked];
//[_rootViewController refreshVisibleViewForCellTagged:self.tag];
[self.delegate refreshVisibleViewForCellTagged:self.tag];
}
in RootViewController.h adopt the delegation of MyCell
#import "MyCell.h"
#interface RootViewController : UIViewController <MyCellDelegate>
in RootViewController.m.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = // your implementation
//assuming all your cells are of MyCell kind
// set RootViewController as the delegate of each cell
((MyCell *)cell).delegate = self;
return cell;
}
implement the delegate method in RootViewController.m.
- (void)refreshVisibleViewForCellTagged:(NSInteger)cellTag {
// whatever you have
}
P.S. The above codes are for illustration. I didn't run them. If some part doesn't work, let me know, and I'll revise it.
The reason those objects in RootViewController are nil in the way you call, is because you are not accessing the same instance of RootViewController. It is a different (new) instance and hence all objects are nil.
Ignore the fact that view controllers are even involved. What you have are OBJECTS, connected together in a certain pattern. Accessing data in another view controller is no different from accessing data in any other object. There's no "magic" with view controllers, other than they have a few standardized connections to other objects.
IMHO, this is a poor design. For starters, your cell shouldn't need a reference to the view controller that the table it's in is in (read that twice, it barely makes sense just because the very idea of it is confusing). You have a strong reference to this view controller. So what happens when the OS tries to deallocate your view controller? It will never be able to, because the table view cell as a strong reference to it, keeping its retain count at 1. The same situation holds true for the cell. You risk running into a retain cycle here. Generally, child views should have weak references to their parents.
But this isn't even really a true parents/child relationship. I would suggest instead an approach like this, which all occurs in your view controller that contains the table view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Assuming you set a reuse identifier "cellId" in the nib for your table view cell...
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:#"cellId"];
if (!cell) {
// If you didn't get a valid cell reference back, unload a cell from the nib
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:nil options:nil];
for (id obj in nibArray) {
if ([obj isMemberOfClass:[MyCell class]]) {
// Assign cell to obj, and add a target action for the checkmark
cell = (MyCell *)obj;
[cell.checkMarkButton addTarget:self action:#selector(checkPressed:) forControlEvents:whateverEventYouWant];
break;
}
}
}
// Set the tag of the cell here, since we may get a different cell back from the reuse queue
cell.checkMarkButton.tag = indexPath.row;
return cell;
}
Now set up the method for the clicking of the checkmark button
- (void)checkPressed:(id)sender {
UIButton *checkmark = (UIButton *)sender;
// This will give you the row of the checked button
int checkedCellRow = checkmark.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:checkedCellRow inSection:0];
// Now you can grab a reference to that cell if you need to
MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
}
This way, you keep all of the controller-related stuff in your controller class (i.e. how to handle the checkmark button being pressed), and you don't need to deal with this whackiness of referencing the view controller of your cell's table.
EDIT: I guess I should also help answer your questions...First of all, if you're saying that in your refreshVisibleViewForCell method, you're getting a nil value for self.myTableView, are you sure it is hooked up properly in IB? Even if it's hooked up, click the little x to unhook it and hook it up again to be sure. Also make sure you've #synthesized your myTableView property. Without seeing more code, an IB issue is my best guess as to why you're getting a nil value for tableView. A nil value here will result in a nil indexPath and selectedCell, also. As for your big question, you can access properties of objects within your view controller. Those properties can, of course, be objects. So in your example, if you have a tag property on selectedCell, you can access it from anywhere that you have a valid reference to selectedCell. If selectedCell is nil, the property will be nil. #class is better suited for header files. For instance, if you wanted to make your custom cell a property of your view controller, you might say:
#import <UIKit/UIKit.h>
#class MyCell;
#interface RootViewController : UIViewController
#property (nonatomic, strong) MyCell *cell;
#end
Then, in your implementation file, you would actually import MyCell.h. Giving the #class forward declaration just keeps you from having to import all of the details about the MyCell class in your header file. The header doesn't need to know about all of the properties and methods of MyCell, just that you intend on using it in the implementation file. So you #class in the header, #import in the implementation.
in RootViewController.h:
#interface RootViewController : UITableViewController <UITableViewDelegate>
in RootViewController.m:
- (void) refreshVisibleViewForCellTagged:(NSInteger)cellTag {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
MyCell *selectedCell = (MyCell*)[self.myTableView cellForRowAtIndexPath:indexPath]; // nil
etc...
I'm not seeing declarations of myTableView in your RootViewController. But if your RootViewController implements UITableViewController, you can use self.tableView to access the tableview. You don't need to keep a reference to it by yourself.
#RachelD, if your RootView is more complicated than just a UITableViewController consider using a separate class, such as RootTableViewController. Then in your RootView xib, create IBOutlet for RootTableViewController to reference it. Like this:
// RootTableViewController definition
#interface RootTableViewController : UITableViewController
{
}
// RootViewController definition
#interface RootViewController : UIViewController
{
RootTableViewController *table_c;
}
#property (nonatomic, retain) IBOutlet RootTableViewController *table_c;
Note that you need to drag an "Object" into the "Objects" section (for RootViewController) in the interface builder, and type RootTableViewController in the Custom Class section for this object. Right click this object, make sure its IBOutlet, view, 2 delegates are correctly set.
The reason why your myTableView is nil is because it's not properly initialized. I mean, if you don't use UITableViewController you are responsible for assigning it manually via interface builder or something.

Multiple TableViews in a single screen

I have a UIViewController that I plan to have two TableViews and some other items in.
Both TableViews I am using on other screens, so I want to make them as independent and reusable as possible. One of those TableViews is called messageList (A UITableView) which shows my ChatHistory.
I am trying to understand if my approach is. [Edited 9/2 with correct code to make this approach work]
One approach would be to use a single table with 2 different sections, then in the delegate methods use a conditional statement to see which section is which and act accordingly.
The problem with this approach is usability. I want to easily reuse my TableViews in other views where one or the other TableView may or may not exist. Additionally, I want the DataSource to exist throughout the lifecycle of the app regardless of what Controller is instantiated or active.
My approach is to separate the view controller that manages the table view's from the table UITableViewDataSource and UITableViewDelegate implementations. But I am having a problem making this work.
Focusing on one of the TableViews, my ChatTableView.
In my AppDelegate has a property for chatHistory of type ChatHistory which implements UITableViewDelegate & UITableViewDataSource.
// AppDelegate.h
ChatHistory *chatHistory;
...
#property (nonatomic, retain) ChatHistory *chatHistory;
// ChatHistory.h
#import <Foundation/Foundation.h>
#interface ChatHistory : NSObject <UITableViewDelegate, UITableViewDataSource> {
UITableViewCell *nibLoadedCell;
NSMutableArray *messages;
}
#property (nonatomic, retain) UITableViewCell *nibLoadedCell;
#property (nonatomic, retain) NSMutableArray *messages;
#end
// ChatHistory.m - Note this code, including the custom cell was working correctly when it was a part of the controller so I believe it should be correct
#import "ChatHistory.h"
#include "ChatMessage.h"
#implementation ChatHistory
#synthesize nibLoadedCell; // custom cell design
#synthesize messages;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [messages count];
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
return [NSString stringWithFormat:#"Discussion"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"ChatTableCell" owner:self options:nil];
cell = nibLoadedCell;
}
// custom tag order - username; message; future - Avatar; like; dislike
ChatMessage *obj = [messages objectAtIndex:indexPath.row];
UILabel *messageLabel = (UILabel *) [cell viewWithTag:1];
messageLabel.text = obj.message;
UILabel *usernameLabel = (UILabel *)[cell viewWithTag:2];
usernameLabel.text = obj.sender;
return cell;
}
- (void)dealloc {
if (messages) [messages release];
[super dealloc];
}
#end
// MyViewController.m
- (void)viewDidLoad { // MAKE SURE TO INITIALIZE viewDidLoad not InitWithNib
if (!appDelegate.chatHistory)
appDelegate.chatHistory = [[ChatHistory alloc] init];
messageList = [[UITableView alloc] initWithFrame:CGRectMake(0, 54, 320, 100) style:UITableViewStylePlain];
messageList.dataSource = appDelegate.chatHistory;
messageList.delegate = appDelegate.chatHistory;
[self.view addSubview:messageList];
...
You do not need to make a view controller your tableview DataSource or delegate; any object can be set. You can use a singleton as Felix suggests, or any other class structure you want. Since you mention that you want the chat history to be available from anywhere in the app, it makes sense to provide a UITableViewDataSource protocol to that chat history.
As for the UITableViewDelegate, you can simply create a new class as a subclass of NSObject and implement the delegate there. Make sure it's created and retained properly, and set in (upon load) as the delegate for your table views.
If you want one central data store, you could create a Singleton class with the data.
Then set it as the data source for the table view or fetch the array (or whatever you got) from the data store in your UIViewController / UITableViewController.
If you initialize the data store in your AppDelegate, you can access it from every class you want (note that all data you load, will remain in memory until your application gets terminated by iOS)
How to create a Singleton class in Objective-C
I would do it this way: make the two UITableViews subviews of one view controller.
In each of the datasource methods you simply distinguish between the two tables, similar to the code Apple provides in the UISearchDisplayController examples. For instance:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == myTableView1) {
// return appropriate number of rows
}
// return appropriate number of rows for the other table view
}
I know this does not separate the two table view classes very neatly. You would have to have a view controller controlling two other view controllers, one for each tableview.
Perhaps one has to consider the tradeoff between reusability and the complications of a more convoluted architecture (which typically also leads to classes that do not perform all that well in terms of reusability). That's why I would recommend the approach from the Apple sample projects.

Simple way to separate UITableview datasource and delegate from main UIViewController class?

The typical UITableView usage pattern is to have the main UIViewController become a target datasource and delegate for the UITableView it is holding on to.
Are there any simple and easy to follow tutorials that would help me figure out how to move the code that pertains to the UITableViewDelegate and UITableViewDataSource methods into a separate class and hook that to my UIViewController instead? I would ideally like to have both the delegate and datasource living in the same class.
Right now, I am creating the UITableView via Interface Builder and connecting its outlet to my controller class.
Typical code:
#interface MyController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableview *myTableview;
}
I want to do something more like this:
#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
I spend 2 hours to solve this problem:
It's working for me
// 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
First thing is if you're using a UITableViewController subclass with interface builder you will want to disconnect the delegate and datasource outlets that are already hooked up by default. (Hint, look in the connections inspector). Check even if you have a tableView inside a viewController.
Second create your classes and make sure they conform to <UITableViewDelegate> and <UITableViewDataSource>. You're probably going to have to declare this contract in the .h file if you're using objc.
Third, In your view controller instantiate this class or two separate classes somewhere like viewDidLoad, and then assign self.tableView.delegate = myCustomDelegateInstance and self.tableView.dataSource = myCustomDataSourceInstance.
Now, any calls that come through the controller will be dispatched to your custom handlers. Pretty basic.
The only reason to really do this is if you 1) have a very bloated controller, or 2) you need to reuse the dataSource and delegate methods somewhere else and you want to avoid code repetition. Otherwise, it's probably better practice to leave it put.
You can create separe classes (with UITableViewDelegate , UITableViewDataSource) and add them in IB as external files and link the IBActions
In IB, you can drag a 'External Object' from Library->Cocoa Touch->Controllers into your xib window. You can then select that object, view the inspector, and set the class. It is now available to serve as a delegate, etc.