Added table view cells follow 1 custom style? - ios

I am wanting to create a custom UITableView cell. I would like to know how to do this. I understand how to actually create it and write code for it, but how can i create 1 style and then when i have more cells added, i want the same style. How can i do this? Is there a way to create 1 custom cell and have all the other cells that i want to add later follow this cells style?Thanks for the help!

In my projects I'm implementing method that creates custom style programmatically. Also it is possible to make custom cell via IB and when you need just take custom cell from it.
Don't forget that if you will write your code correctly then your cells will be reused and that method will be called only for number of cells that are visible in your table view.

may be this can help you http://iphone-bitcode.blogspot.com/2011/06/custom-tableview-cell.html

Write a separate .h/.m/.xib for the cell, and in the .xib set File's Owner to the class you want multiple copies of it in (your table view controller class, most likely). Attach it to an IBOutlet you created in the table view controller for new cells.
Then, each time you want a cell, try and dequeueReusableCellWithIdentifier: on your tableView, and if that doesn't work (you have no reusable ones), make a new cell using your custom class by simply loading the nib file. It will automatically create an instance of the cell and attach it to your IBOutlet, and then just retain the cell and set the outlet back to nil for the next time you need to create a cell. Essentially, I mean this (I have an IBOutlet UITableViewCell *cellOutlet):
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier = #"CustomCell";
UITableView *cell = [self.tableView
dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"MyCustomTableViewCell"
owner:self options:nil];
cell = cellOutlet;
self.cellOutlet = nil; // autoreleases
cell.reuseIdentifier = reuseIdentifier;
}
// configure the cell here
return cell;
}

Related

Can't access a UIButton when it's created dynamically in UITable view cell?

I've created a UIButton dynamically in the table view cell. but there is a problem,- I'm not able to access the button or it's sender method.
When I click on a button it's giving the wrong tag or sometime it's not clickable. I've created button a with the help of for() loop in the tableview cell. I think the main problem is that I create the button in the for() loop. Can anyone help me to solve this issue?
My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIView *viewDisplaySize;
if (cell == nil)
{
NSString *myString =#"1111111:2222222:333333:44444:55555:6666:777777:888888888888:9999999999" ;
NSArray *myWords = [myString componentsSeparatedByString:#":"];
for (int i=0; i < [myWords count]; i++) {
//Create a button but can't able to get a correct tag
/// Or some time it's not click able
}
Whole code--- link of full code
The basic problem is that the way you're adding your subviews is not the best way. By adding the subviews inside a if(cell == nil) clause, and setting the tag value there, the tag value will never change. When the cell is reused, the tag will still be based on the row where it was created, not on where that reused cell now appears.
A better way to create your cell, would be to add any subviews you need in the init method of a custom cell class. This cleans up the code in cellForRowAtIndexPath so it only contains code you need to populate the cells. If the cell is made completely in code (no xib or storyboard for its view), then you should register the class (usually done in viewDidLoad of the table view controller) with registerClass:forCellReuseIdentifier:. Then, in cellForRowAtIndexPath there will be no need to check whether the cell is nil because it never will be. You still want to set the button's action and tag in cellForRowAtIndexPath, but now it will be reset for the proper row when the cell is reused.

How to add more than two labels to prototype cell?

I have gone through the tutorial below and it works fine. My question is how do I add more than the two standard cells to the prototype cell?
http://thedarkdev.blogspot.co.uk/2013/09/web-service-apps-in-ios7-json-with.html
cell.textLabel.text = "Title Text";
cell.detailTextLabel.text = "Detail Text"
I am wanting to add another 4 labels and would like to lay them out using the storyboards.
Any ideas how to do this?
You can use a custom cell type and you'll be able to add as many labels as you want:
Create a empty UITableViewCell subclass that you'll use for this cell. Note, this subclass doesn't need any code inside its #implementation. We're only going to add outlets for its properties, and those will show up in its #interface, but the storyboard eliminates the need to write any code for the cell, itself.
Back in Interface Builder, go to the table view in your storyboard and make sure it has a cell prototype. (If it doesn't drag one from the object library on to the table view.)
Over on the "Identity" inspector panel on the right, set the base class of the cell prototype to be your UITableViewCell subclass as the cell prototype's "base class";
In the storyboard's "Attributes" inspector for the cell, set the cell "Storyboard identifier" to something you'll reference down in step 5 (I've used CustomCell here);
Set the cell "Style" to "Custom" rather than "Basic" or "Detailed":
add your labels to the cell.
I've added for labels to a single prototype cell here:
Use the "Assistant Editor" to show your code simultaneously with the storyboard. Select one of the labels you've added to the scene, change the code down below to be the UITableViewCell subclass you created in step 1, and you can now control-drag from the label to create IBOutlet references for the labels to the cell's custom subclass:
By the way, I'd advise against using IBOutlet names of textLabel or detailTextLabel (not only are they too generic, but it can get confused with the labels that appear in standard cell layouts).
Now your tableview controller can reference this subclass:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell"; // make sure this matches the "Identifier" in the storyboard for that prototype cell
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// retrieve the model data to be shown in this cell
// now fill in the four labels:
cell.firstNameLabel.text = ...;
cell.lastNameLabel.text = ...;
cell.emailLabel.text = ...;
cell.telephoneLabel.text = ...;
return cell;
}
So while there are a couple of steps to go through here, the net result is that you can design whatever cell layout you want, and with this very simple UITableViewCell subclass, your cellForRowAtIndexPath is incredibly simple, just referencing the IBOutlet references you connected in Interface Builder.

Cannot set properties on custom table view cell

I have a problem settings my view elements on a custom cell. The table cells appear in my tableView, but the properties do not set and thus only empty/blank cells appear.
The tableView is not a tableView controller, but only a tableView in a viewController.
I have the following files:
CustomCell.xib:
Here i use IB to build the custom cell by using a Table View Cell from object library with labels and images on. I set the Identifier as orderListCell. From this screen I ctrl+drag to create the outlets in customCell.h
CustomCell.h
Here I see all my IBOutlets as properties from above mentioned file
CustomCell.m
Here I leave as is
OrderListViewController.h
Here I import customCell.h and use protocols UITableViewDelegate, UITableViewDataSource
OrderListViewController.m
Here I set my tableView delegate and tableView dataSource to self. I also create an IBOutlet for my tableView from the Storyboard.
I use the following code to try and display my cells:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"orderListCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[CustomCell alloc] init];
}
cell.myLabel.text = #"aaaaaaaa"; //[[self.orders objectAtIndex:indexPath.row] objectForKey: #"tableNo"];
return cell;
}
I have simplified my code a bit to demonstrate that even setting the label to a simple string (#"aaaaaaaa") doesnt work. When I look at the objects in my debugger the cell does have all the properties from the IBOutlets and the cell does appear in my tableView, just the label.text = xxx does not seem to work.
I have looked at the following posts but either dont understand it properly or it does not work for me:
ios 7 customizing UITableViewCell's content view
Can't set properties in Custom UITableViewCell
Set label for a custom cell
Any help or advice would be greatly appreciated
cell = [[CustomCell alloc] init]; does not create your cell from the XIB, so none of the XIB content will be created.
Use registerNib:forCellReuseIdentifier: to register the XIB with the table view so that it will create your cell instances for you (you don't need to create instances yourself in cellForRowAtIndexPath).
If you don't want to do that, you can load your NIB explicitly with nibWithNibName:bundle: and instantiateWithOwner:options:, then get the cell instance from the list of returned views (which should only contain 1 item).

How to alter tableview cell text?

I have a UITableView that I want to alter some of the static cells after I do other processing. I have outlets set up for the cells that I want to modify, but when I look at them using NSLog, they show nil, which indicates to me that I don't have the correct cell. For instance, in the image below I want to add the start time to the label just like I did for Date (date was done when creating the cells for which I got the current date),
I tap on the disclosure indicator which takes me to another scene (this was created in Storyboard, using segues to get from one scene to another) where I get the two times I need. I then return to the main scene (shown) and try to alter the Start Time label, but nothing happens. A NSLog of the label prior to trying to alter it returns this:
oStartTimeCell.textLabel.text: (null)
I have read in one of the Apple docs that this textfield is read-only. If that is true in this case, is there a way I can reload the cells with the updated information? Or is there another way to do this?
You're using the wrong approach. You should not create a reference to a cell using an outlet. Once the cell moves out of the visible view, the outlet will either be null or contain garbage data. Even if (in your situation) the cell will never move out of view, I think it shows you're trying to use a UITableView in a way that was not meant to be.
Instead put the data you want to display in your cells in a dataSource, e.g. an array.
The tableView should use the dataSource to configure the values displayed in the textLabels of the cells. Once you want to update the text displayed in the cells, change the values in the dataSource and call reloadData on the tableView to force the tableView to call -tableView:cellForRowAtIndexPath: and related UITableViewDataSource methods.
Try to create an IBOutlet for each cell and connect it:
IBOutlet UITableViewCell *cell1;
IBOutlet UITableViewCell *cell2;
IBOutlet UITableViewCell *cell3;
And also change your method to:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(indexPath.row == 0) return cell1;
if(indexPath.row == 1) return cell2;
if(indexPath.row == 2) return cell3;
if (cell == nil) {
//create cell;
}
return cell;
}
Are you using a UILabel to display the text ? . If you are just create an outlet to the UIlabel and update it any method like cellForRwoAtIndexPath or didSelectRowAtIndexPath etc that is called after you tableView is loaded.
If you are not using a UILabel and just using cell.textLabel you could do something like
cell.textLabel.text = #"ChangedText" in cellForRowAtIndexPathMethod. Make sure you are editing the required cell by checking indexPath.row
Do [tableView reloadData] to call cellForRowAtIndexPath.

How do I have a UITableView with two different cell types and set each of the`cell layouts up programmatically, instead of via a Storyboard?

Previously I had this set up with a storyboard, having dragged the UILabels, positioned them and sized them whatnot on the UITableViewCell I dragged them onto, and then do a different version of that for the other UITableViewCell.
For example, like follows (but in the picture they've yet to be customized with the labels):
Then in the datasource, I'd simply check the Identifier, and depending on what the Identifier was, customize the cell accordingly.
However, I've needed more customization than I can get from the storyboard, as each cell is going to have two UIViews (a top one and a bottom one to allow sliding of the top one) so I can't really do this with storyboarding, as I add the labels and everything to the UIView programmatically.
But my question is: When I do it programmatically, how can I tell which cell is which so I can customize the layout of the UILabels accordingly? With a storyboard I can obviously just drag a UILabel onto each one, but when doing it programmatically and setting up the UIView, I don't know how to say, "Hey, if the identifier is this, add the UILabels like so" because the UIViews aren't aware of any Identifiers.
Basically the structure looks like this:
UITableView -> UITableViewCell -> CellFront(UIView) & CellBack(UIView)
And the look of the cell comes from the labels added to the CellFront UIView. But there's two looks to the cells and I don't know how to do it without a storyboard.
Although UIViews are not aware of identifiers, they have a property called tag which can be used for any purpose that you would like. You can set the tag to, say, 1 on cells of one kind, and to 2 on cells of the other kind, and then use the tag to distinguish the cells in code. Moreover, once your views are tagged, you can call viewWithTag: on the containing view, and get back the view with the tag that you want.
If you are creating the cells solely in code, then you register your UITableViewCell subclass in the viewDidLoad method of your table view controller. That method sets the identifier. Then, you use that identifier in cellForRowAtIndexPath: just like you would for a xib or storyboard created cell.
[self.tableView registerClass:[MyCellSubclass class] forCellReuseIdentifier:#"MyIdentifier"];
Here is one approach:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Adjust the condition to match your needs
if (indexPath.row == 0) {
static NSString *Identifier1 = #"CellType1";
// cell type 1
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier1];
// add subviews here
}
// set cell properties
return cell;
} else {
static NSString *Identifier1 = #"CellType2";
// cell type 2
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier2];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier2];
// add subviews here
}
// set cell properties
return cell;
}
}

Resources