Using UITableViewCell in a UITableView - iphone

I'm a little confused with something. I'm trying to create a custom cell and I want to use the interface builder way.
The normal way I create a table is to have the table as:
.h
#interface AssessList : UIViewController {
IBOutlet UITableView *tblAssessList;
}
#property(nonatomic, retain) UITableView *tblAssessList;
#end
.m
- (NSInteger)
numberOfSectionsInTableView:(UITableView *)tableView {
return groupArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return totalArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = #"I am the text....";
return cell;
}
Now i've created a new class for the cell and I think I understand how to put that in. But can I leave the .h as
#interface AssessList : UIViewController
or does the class/nib with the full table on it have to be a UITableViewController?
Tom

does the class/nib with the full table on it have to be a
UITableViewController?
No. A UITableViewController is just a convenience UIViewController subclass which has a UITableView and is already setup as its delegate/datasource (it is declared as conforming to the UITableViewDelegate and UITableViewDatasource protocols), it also has pre-filled method implementations for these protocols in the template implementation file which Xcode generates for you. You can just as well do all of this yourself, I often do.
You should however make an IBOutlet for your UITableViewCell so that you can load it from the nib file (see the Loading Custom Table-View Cells From Nib Files in the Table View Programming Guide).

If you want to do in the Interface Builder Way, then create an xib (view xib). Drag and drop a UITableViewCell object from the obj palette. Customize it as you wish. In the tableView:cellForRowAtIndexPath: method, do this:
UITableViewCell * aCell = [tableview dequeueReusableCellWithIdentifier:#"SomeIdentifier"];
if (aCell == nil)
{
NSArray *arr = [[NSBundle mainBundle] loadNibNamed:#"CustomCellNibName" owner:self options:nil];
for (NSObject *anObj in arr) {
if([anObj isKindOfClass:[UITableViewCell class]]) {
aCell = (UITableViewCell *)anObj;
}
}
}
The identifier for the tableviewcell can be set in the IB.

I guess it should be sub class of UItableViewCell
i.e.
#interface AssessList : UITableViewCell

When you want a custom tableview cell you will also need a subclass of UITableViewCell..
A tutorial can be found on this blog
Keep in mind that quite a few things can be done without creating a custom cell, this includes adding the switch to make your tableview look like the one from settings.app, to the way the iPod displays songs.

In the assessList Class you are using the custom cell created in otherviewController (UITableViewCell subclass) so there is no need to change this line
#interface AssessList : UIViewController
Note:- the otherviewController should be a subclass of UITableViewCell

Related

How to control a customized UITableViewCell within a UITableView Implemented within a UIViewController?

In my app I wish to have a UIViewController that will hold a UITableView in it. In this UITableView I wish to have a customized UITableViewCell (i.e. I wish to define my own elements in this CELL - image, labels and buttons - as seen in the image below). And... I want to create them in the Storyboard.
Now, setting the elements in the Storyboard is easy.
I understand how to connect the UITableView and set it in the UIViewController (including the delegates in the .h file and using the basic table delegate methods).
What I'm not clear about, is how to connect and control the customized UITableViewCell and its outlets. Can I create the Outlets and Actions within the UIViewController .h and .m files? Do I need to create a separated UITableViewCell.h/.m files and call on them in the cellForRowAtIndexPath method?
Can anyone suggest what's the best approach for my needs?
UPDATE:
Here is the code I used in cellForRowAtIndexPath while using the separated MyCell.h/m file option. This code is written in the ViewController.m file, where the UITableView is implemented.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContentCell";
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//MyCell is the Objective-C Class I created to manage the table cells attributes.
//#"ContentCell" is what I had entered in the Storyboard>>UITableViewCell as the Cell Identifier.
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//Here is the place I'm not clear about - Am I supposed to init the cell in a different way? If so, how?
}
cell.contentNameLabel.text = [self.dataArray objectAtIndex: [indexPath row]];
// this is the test I had done to check if the new "MyCell" object is actually getting what I would expect it to get. well... the text gets updated in the relevant label, so i guess it gets it
return cell;
}
When running the app, using the debugger break point, I can see that the code always skips the "if (cell == nil)" and never enters the code where the new MyCell object supposes to be allocated and initiated. Any idea what may I be doing wrong?
Correct, create separate UITableViewCell.h/.m files to match your custom UITableViewCell class and call on them in your cellForRowAtIndexPath method.
In your storyboard, set the class of your custom UITableViewCell to your custom class (e.g. CustomTableCell).
Your custom UITableViewCell class would contain IBOutlets which you would wire up in your storyboard, here is an example:
CustomTableCell.h:
#import "CustomStuff.h" // A custom data class, for this example
#interface CustomTableCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *titleLabel;
- (void)configureForCustomStuff:(CustomStuff *)stuff;
#end
CustomTableCell.m:
#import "CustomTableCell.h"
#implementation CustomTableCell
#synthesize titleLabel;
#pragma mark - Configure the table view cell
- (void)configureForCustomStuff:(CustomStuff *)stuff
{
// Set your outlets here, e.g.
self.titleLabel.text = stuff.title;
}
#end
Then, in your cellForRowAtIndexPath method, configure your cell:
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomCellID"];
// Your custom data here
CustomStuff *customStuff = <YOUR CUSTOM STUFF>
[cell configureForCustomStuff:customStuff];

UITabBarController with UITableView

i am trying to display a list on my first view so added this in the first.h :
#import <UIKit/UIKit.h>
#interface argospineFirstViewController : UIViewController
<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *Journals;
IBOutlet UITableView *myTableView;
}
#property (nonatomic,retain) NSMutableArray *Journals;
#property (nonatomic, retain) UITableView *myTableView;
#end
and then i added this on my first.m :
#implementation argospineFirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Journals=[NSMutableArray arrayWithObjects:#"journal1",#"journal2",nil];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
cell.text=[Journals objectAtIndex:indexPath.row];
return cell;
}
I am newbie so i don't really know what kind of connections i have got to make, i am also using a storyboard with a tableview dropped on the first view.
is there something i have to add to the delegate?
Any help?
Thank you for your time
Right click on the tableView in the storyboard. You will see "delegate" and "dataSource" under Outlets. Drag the bubble on the right of those to the view controller icon at the bottom of the view. This will make your viewcontroller the delegate and datasource for the table view if you don't want to do it programmatically.
Do not make property of your table view object.
Also,
in viewDidLoad method write:
myTableView.dataSource = self;
myTableView.delegate = self;
Tell me if it helps!
Use initWithStyle instead of initWithFrame for creating your cell.
In your storyboard, select your table view and open the Connections Inspector. Make sure that the delegate and datasource connections are linked to your argospineFirstViewController object.
in IBOutlet set delegete and datasource of the tableview to filesOwner
you use cell.text for show the data i think its not work in tableview just try this line:-
cell.textlabel.text=[yourArrayname objectatindex:index.row];
no need to connect delegate you already define in protocol.

Reusable TableViewCell in Interface Builder WITH changeable labels?

How do I make a reusable TableViewCell in Interface Builder with changeable labels?
Is this even possible? From what I understand apple has been giving custom TableViewCell in Interface Builder some love lately, so this should be possible?
Ps. I know there are a lot of questions with answers about TableViewCell in IB, but I couldn't find anyone that made labels work.
You can change anything in a cell that is being re-used. To customize labels that you create in IB, you should set their tags in IB itself & fetch the label using the same tag.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MyCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[MyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
//Do anything here with the labels. Even add or remove them.
(UILabel*) label1 = (UILabel*)[cell viewWithTag:1];
return cell;
}
I used to do it he same way as in accepted answer, but I've always felt using tags like I'm using "go to" in Pascal. Feels dirty. But maybe it's just me, tags work just fine.
There's an alternative way though. Subclass a UITableViewCell, create an IBOutlet property, connect in IB, and reference your property in cellForRowAtIndexPath: code. Like so:
interface MyCustomCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *myAwesomeLabel;
#end
Don't forget to set you cell's class to MyCustomCell in IB.
After that you can connect your property in IB directly like so
And in your Table View Data Source now you can access this property
#import "MyCustomCell.h"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell) {
cell.myAwesomeLabel.text = #"Hello, World!";
}
return cell;
}
Using tags is error-prone and might turn into a mess very quickly if you use a lot of them.

How can i add objects into UITableView?

How can i add objects into UITableView?
You have to first take IBOutlet Object of UITableView in interface file and then bind it using interface builder. Set delegate and data source of UITableView in the interface builder property.
And do the following coding in your project.
In .h file:
#interface RootViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource> {
IBOutlet UITableView *tblView;
}
In .m file:
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return n;// n for number of row.
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
return cell;
}
Implement the UITableViewDataSource delegate methods.
Also check out the Table View Programming Guide.
Tableviews are populated by datasources, datasources are often an array of objects.
I suggest you look through some tutorials on tableviews and also delegate methods.
http://icodeblog.com/2008/08/08/iphone-programming-tutorial-populating-uitableview-with-an-nsarray/
icodeblog is a fantastic website for beginners.

UITableView works in 3.2 but no tableview methods are firing in 4.0 (simulator & device)

I just came across a situation where my implementation of a tableview is working in 3.2 but fails to fire any of the tableview methods in iOS 4. The view controller in question is defined as a UIViewController and is setup to adopt the UITableViewDataSource and UITableViewDelegate protocols, and I'm hooking the tableview up as the view's datasource and delegate via IB.
Definition in .h:
#interface FooViewController : UIViewController <UITableViewDataSource,
UITableViewDelegate> {
IBOutlet UITableView *itemTable;
}
#property (nonatomic, retain) IBOutlet UITableView *itemTable;
.m:
#synthesize itemTable;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"numberOfSectionsInTableView fired!");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
NSLog(#"numberOfRowsInSection fired!");
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
This appears to work fine in < 4.0, but in 4 it just simply bypasses firing any of these methods. Am I by chance doing it incorrectly and being caught up by something being fixed in 4.0?
Do you have the dataSource and delegate set for the itemTable? The rest of your code seems to look fine. Another question is why use the UiViewController instead of using the UITableViewController
I've been using the UITableViewController and it works quite well, and you can still just implement the simple basic methods you have implemented.