Reusable UITableView's prototype cell - ios

I want to create a prototype cell which can be used in different table view via the storyboard.. What is the right way to do this? Any pointers appreciated.

I don't think you can create a prototype cell and share it between tables in a storyboard, but you can create a prototype cell in a nib and then load that in the ViewDidLoad method and then use that in your table view. It is really quite simple, here is how...
A. add the nib file:
1. Select New File...
2. Select IOS -> User Interface
3. Select "Empty" -> this will add a new file .xib file to your project
4. Drag a UITableViewCell from the object browser into your xib file and customize to your liking
5. Use the Utilities pane to change properties -> editing a nib is very
similar to editing a storyboard.
6. Make sure you name your cell - I chose the name cellFromNib, but you will probably want something else.
B. Load the UITableViewCell in each table's viewDidLoad method:
- (void)viewDidLoad
{
// load the cell in the nib - the nib can only contain this one UITableViewCell
[self.tableView
registerNib:[UINib nibWithNibName:[self #"nibFileNameWithoutExtension"]
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:[self #"cellFromNib"]];
}
C. De-queue the nib's tableViewCell...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellFromNib" forIndexPath:indexPath];
// customize your cell here...
}
D. Add a "dummy" prototype cell to your TableView in your storyboard.
Make a segue from this "dummy" cell to the view you want displayed when the cell is selected - make sure to name the segue - I'll call it #"theSegue" for this example. You will reference this segue in your code.
E. Finally, add code to segue from that cell...
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// this is basically what the storyboard does under the hood...
// make sure you have a "dummy" prototype cell with this segue name for each
// tableview that uses this cell
[self performSegueWithIdentifier:#"theSegue" sender:self];
}
If you want to specialize your cell code, create a class that subclasses UITableViewCell
I think that is everything you need.
I would say do not be afraid of doing something like this because, if you are serious about IOS programming, you will learn something new. It really does make for much better reusable code.

Related

Adding UITableView to ViewController

I haven't developed any iOS apps in a while. I am fine with both swift and Objective-C but what I find different is adding a UITableView to ViewController. Before, I used to add a UITableView to ViewController, add the required datasource methods and the typical UITableViewCell object, and return the cell in cellForRowAtIndexPath:, which would display empty cells depending on the number of rows I return. Now, I did everything the same, but the UITableView is empty and when I scroll I see the lines but not my cell.textlabel.text value, which I set. It seems now I am supposed to add UITableViewCell to the UITableView and remove the
#pragma-mark TableView Datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_formTitles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell==NULL)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cell"];
}
cell.textLabel.text=[_formTitles objectAtIndex:indexPath.row];
cell.detailTextLabel.text=#"Kaushik";
return cell;
}
I can't find a simple post online regarding the same.
Can someone post what are the changes in the new iOS 9 in a simple manner?
Thank you
Right..For those of you who are still prefer to add a tableview to a viewcontroller.Here are the steps
In the ViewController drag and drop the tableview.Now instead of the lines which you see in the old Xcode.This time you would see a blank table view with the text " Table View prototype content" in the middle.
We usually create a tableviewcell only we doing anything different like adding more labels or image etc but hereafter it is required to add a tableviewcell in the tableview.Drag and drop a tableview onto the tableview.It will display as protype cells.One can select type of cell here itself as basic,value 1,value 2 or subtitle.Also NEED TO SET THE REUSE IDENTIFIER IN THE STORYBOARD UTILITIES PANEL ON YOUR RIGHT. At the end, you can select the tableview and add the missing constraints.
Implement the typical required datasource methods in your viewcontroller class.
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.textLabel.text=#"text";
cell.detailTextLabel.text=#"DetailedText";
return cell;
}
The change here is that we dont require the usual if(cell==nil)
{..}
piece of code since we added the prototype cells to the storyboard.
Don;t forget to connect the delegate and datasource of the tableview to the viewcontroller.
This should display the tableview in your viewcontroller but i am getting a space on top of the tableview which i don't know why.Anyway this is how you add a tableview to a view controller using Objective-C language in iOS 9.3.
FYI: Guys if i've missed anything, please mention it in the comments
Thank you
Put tableView to view controller and link it to viewcontroller.
link delegate and datasource of tableview to viewcontroller.
in
viewcontroller.h
#interface ViewController :<UITableViewDelegate, UITableViewDataSource>
in viewWillAppear put
tblService.delegate=self;
tblService.dataSource=self;
and your array elements.
5.Impliment your tableview delegate method and datasource method .
6.be sure you cell identifier equal the one put on storyboard.
this link will help you more to implement your first app and this video.

How should I implement a custom table view cell?

I am trying to change a cell in a tableview from generic to custom and have created a new tableview cell class. However, I cannot get the cell to recognize the new custom cell. Instead, it is still displaying the generic cell although I've changed the setting in storyboard to custom in the identify inspector and also changed the class for the tableview cell to the new custom one. I have also wired the elements in the cell in storyboard to the new custom class.
My understanding is the tableview VC knows which class to use from the tableView cellForRowAtIndexPath method and I have changed that too with the code below. The project compiles but continues to show old generic cell. Can anyone see error or suggest what else to do?
#import "customCell.h"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell *cell = (customCell *)[self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
Items *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
return cell;
}
Thanks in advance for any suggestions.
Edit:
A custom cell is created in the storyboard on top of tableview by dragging uielements. Maybe this is an issue:
Style of cell is set to Custom:
You need to create new UITableViewCell and enable the "create XIB file...".
Create your custom cell in the XIB and make it's custom class as your class you just created.
Then in tableView cellForRowAtIndexPath register the Nib: (it's in swift but I bet you can figure out the objective c parallel...)
tableView.registerNib(UINib(nibName: "YourUITableViewCellClass", bundle: nil), forCellReuseIdentifier: "YourCustomIdentifierFromTheCustomClass")
Then access your cell:
var cell = tableView.dequeueReusableCellWithIdentifier("YourCustomIdentifierFromTheCustomClass")
and that's it.
you can create custom cell in your main story board by drag the cell view.
create custom class for that prototype.
mention the class name in identifier inspector.
import that class to your view controller .h file.
and made connection of your custom from main story board to custom class.h file.
it works!.
When you create a custom cell you have to do these things:
Setup the labels, images etc on storyboard cell.
Create a custom cell class (inheriting from
UITableViewCell)(CustomCell.h & .m), CustomCell.h having all of the
properties as iboutlet for labels, images etc. and synthesize them all
in implementation.
After creating this custom class go back to storyboard, select the
custom cell, change its class to the CustomCell and give it some
identifier like "MyCustomCell", then right click on the custom cell
and connect the IBOutlets with labels etc.
Now import CustomCell class in the class where you are implementing
the UITableView and use the properties you defined in CustomCell
class.
- (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
static NSString *MyIdentifier = #"MyCustomCell";
CustomCell*cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the provided setImageWithURL: method to load the web image
// Ensure you use a placeholder image otherwise cells will be initialized with no image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://example.com/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
cell.myCustomLabel.text = #"My Text";
return cell; }
Select the cell on your Storyboard, and enter the name of your class in this field.
When you dequeue it from the identifier, it'll be an instance of that class.
Please note that each regular tableViewCell has a builtin and hidden UIImageView.
In Objective-C, you simply do this within your cellForRowAtIndexPath,
cell.imageView.image = [UIImage imageNamed:#"My awesome image"];
In Swift, it's pretty close.
cell.imageView?.image = UIImage(named: "My awesome image")

UITableView within a UIView within UIViewController in iOs Xcode

I want to achieve the following in xcode.
I have a view controller. Within this UIViewController I have a UITabBar. Below them is a UIView. What is the best way to add a UITableView to the UIView? Then being able to click on a UITableViewCell and opening up another UIViewController to show more information about the UITableViewCell?
Here is the current setup of my storyboard:
Could you offer me a solution to this problem? Thanks
You need a solution to your problem but I'm not sure what your problem is.
In storyboard, drag a UIView in your UIViewController. Then drag a UITableView (not controller) in that UIVIew.
You'll be able to see the view hierarchy on the left.
Then link your tableview datasource and delegate to the parent controller.
in your .h file, add the UITableViewDataSource and UITableViewDelegate protocols, also link your tableview as an Outlet.
In your .m files, add the tableview delegate methods (numberOfRowsInSection: and cellForRowAtIndexPath:)
I also suggest adding didSelect: among the tableview methods because, well, you'll need it.
and you're good to go. :)
It's actually the EXACT same thing as creating a tableview, except that your tableview is a subview of a UIView, which doesn't matter at all if it comes to code. The only thing you'll have to be "careful" of is to build your view properly in storyboard, and make sure the constraints don't make your tableview unusable for some reason.
Check one of my previous answers where I explain how to make a tableview and make it load another controller while passing data, which is something you might need if everything I wrote here still confuses you.
FOLLOW UP:
From your comments I understand that this subview of your UIView can be different things ; a tableview, a webview, and so on.
There are many ways to do that, and from my little knowledge I see two that can be easy and reliable (from my <1year experience as a developer...).
Get all the possibilities ready in your parent viewcontroller, if you only have 2 possibilities for example, that's "okay".
The best way is to prepare a container view (it's literally called container view) which would load different OTHER view controllers according to your needs.
I think option 2 is more reliable, because it will split the code into different classes, will allow you to modify each of them independently, and you can easily remove/add new views.
To my knowledge, you'll have some kind of switch statement in your parent controller that will load the desired UIViewController (or tableview or anything). Whatever you do there will just be as usual, but constricted to a smaller view inside another VC.
You can create that container view in storyboard and pre-link every other VC with segues (ToTable, ToWeb, ToCollection) are good examples for segue names that would link that container view to your 3 UIViewControllers.
Note that you can pass data if need be, but you would have all the separate controllers handle their own stuff even though it is visible inside your current vc.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [catagorry count]; //count number of row from counting array hear cataGorry is An Array
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the provided setImageWithURL: method to load the web image
// Ensure you use a placeholder image otherwise cells will be initialized with no image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://example.com/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
cell.textLabel.text = #"My Text";
return cell;
}
these are the basic method to create a basic table view. to load an view controller corresponing to the cell click u can use did select row method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
/* //Pushing next view
cntrSecondViewController *cntrinnerService = [[cntrSecondViewController alloc] initWithNibName:#"cntrSecondViewController" bundle:nil];
[self.navigationController pushViewController:cntrinnerService animated:YES];
*/
[self performSegueWithIdentifier:#"identifier" sender:self];
}

Why Label Outlets cannot be connected to UITableViewCell Class

I create a table view cell subclass and set it as the class of the prototype.I want to add the outlets to that class and connect them.
But xcode do not respond.
And i try to add the outlets of button in the next time,it works.
I want to display a picture,it is pity that i don't have enough reputations.
I don't understand why this happen.Can somebody help me,Plesae!!
Create a xib file. Delete UIView and drag UITableviewcell.
Set your UITableviewcell class and a identifier for the cell
Drag the components on the cell and connect them with your class.
On the method (void)viewDidLoad of your UITableViewController, set:
[self.tableView registerNib:[UINib nibWithNibName:nameOfXibFile bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:identifierOfCell];
On the method (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath, set:
YourClassTableViewCell *cell = [tableView dequeueReusableCellWithReuseIdentifier:identifierOfCell forIndexPath:indexPath];
and set the values for the labels cell.label.text = #"Your text".
Good luck!
You need to create a subclass for Custom UITableViewCell. Than After you can connect Label outlets.
Check out this great tutorial for creating custom UITableViewCell.
Custom UITableViewCell
To insert referencing outlet by drag you need to do it between #interface and #end statements, like a property (it is actually a property).
You can add a button outlet just because buttons have an action outlets, which are methods.

Loading a UIView within UITableViewCell

I am having an interesting problem creating the custom tableview I need...
I found this question, but it does not really address my issue...
I am trying to put a subclassed UIView inside a subclassed UITableViewCell. The custom view holds a UIButton and a couple labels. Simplified, it's like this:
Both the custom view and custom tableviewcell have xibs.
MyCustomView.xib's class is set to MyCustomView and I have properties for the labels and the button as well as an IBAction for the button.
MyCustomTableView.xib has a property for MyCustomView and is importing MyCustomView.h.
In MyCustomView.xib, I have this init:
-(id)initWithNibName:(NSString *)nibName nibBundle:(NSBundle *)nibBundle myLabelText:(NSString *)labelText {
//The custom view in the tableviewcell is 69 by 64...
if ((self = [super initWithFrame:CGRectMake(0, 0, 69, 64)])) {
[self setmyLabelText:labelText];
}
return self;
}
And in my TableViewController...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomTableViewCell *cell = (MyCustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"theCell" forIndexPath:indexPath];
// Configure the cell...
cell.customView = [[MyCustomView alloc] initWithNibName:#"MyCustomView" nibBundle:nil fileContentID:#"Some Text..."];
return cell;
}
When I run the app, the custom tableview cell's contents are fine, but the content of the custom view inside the custom tableview cell is blank.
It seems that MyCustomView's initializer(-initWithNibName:nibBundle:myLabelText:) don't load any xib.
This post will help you.
How to load a xib file in a UIView
...and MyCustomView should be created once inside MyCustomTableViewCell, as #rdelmar says.
You need to do most of the formatting work in MyCustomTableViewCell - I would not use a XIB and code the views directly because that class is called many times. Apple has number of sample codes regarding TableViewCells - One of them I believe is called Elements that use fancy tableview cells for the Elements of the Periodic Table. Most of my apps use custom cells with icon images and I started with that sample code many years back (since IOS 4).
Your CellForRowatIndexPath should just be passing the image and the label text to your tableviewCell Class instance. If you have question just ask - but I am sure that sample code from apple is sufficient to get you started.

Resources