I want to make custom uitableviewcellstyle to make comments in my app. I want uitableviewcell with comment text, number of likes, author's name, date etc...
Have you any ideas?
I've created method, but I don't know how realize it.
My code:
- (UITableViewCell *)getCommentTableCellWithTableView:(UITableView *)tableView commentText:(NSString *)commentText numberOfRows:(NSInteger)numberOfRows numberOfLikes:(NSString *)numberOfLikes date:(NSString *)date writer:(NSString *) writerName {
static NSString *CellIdentifier = #"TitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
return cell;
}
I'm sorry I can't find a tutorial with clear steps, but you can search some related posts or questions on this site.
Hope the simple code below could help you.
Here is a doc may helps too, take your time to have a look ;)
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
New class inherit from UITableViewCell, CustomCell.h:
(Tips:File->New File->Objective-C class->set class name & choose the subclass UITableViewCell)
#interface MapsListViewCell : UITableViewCell
{
// Add iVars that you want.
}
// Some custom methods
CustomCell.m:
// ...
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
// ...
// Some custom methods
- (void)setAuthorName:(NSString *)name
{
// ...
}
TableViewController.m:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CategoriesListViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
CategoriesListViewCell * customCell = (CategoriesListViewCell *)cell;
// Set your data:
[customCell setAuthorName:#"God"];
// ...etc.
return cell;
}
For those of us using the newer (iOS 6 and up) UITableView API for dequeueing cells namelydequeueReusableCellWithIdentifier:forIndexPath this is actually guaranteed to return an instantiated cell so we can't perform the nil check and manually call initWithStyle. Therefore the best solution is to subclass UITableViewCell and manually enforce the style in initialisation.
So as an example if we wanted a cell with the UITableViewCellStyleSubtitle style we would create a custom subclass:
#interface ABCSubtitledTableViewCell : UITableViewCell
#end
#implementation ABCSubtitledTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
return [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
}
#end
And then in our viewDidLoad we would register the appropriate class
[tableView registerClass:[ABCSubtitledTableViewCell class] forCellReuseIdentifier:NSStringFromClass([ABCSubtitledTableViewCell class])];
Making our dequeue method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ABCSubtitledTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([ABCSubtitledTableViewCell class]) forIndexPath:indexPath];
cell.textLabel.numberOfLines = 0;
cell.textLabel.text = #"Hello";
cell.detailTextLabel.text = #"World";
return cell;
}
Related
I want to create a default static table in my sub-class of UITableViewCintroller, but data doesn't appear. I don't know where is the problem, I think that cellForRowAtIndexPath method not called.
Here is my code:
#import <UIKit/UIKit.h>
#interface S5WebTable : UITableViewController <UITableViewDelegate, UITableViewDataSource>
#end
#import "S5WebTable.h"
#interface S5WebTable ()
#property(assign,nonatomic) BOOL isLoaded;
#end
#implementation S5WebTable
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView sizeToFit];
}
-(void)viewWillAppear:(BOOL)animated{
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 7;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text =#":)";
return cell;
}
I think you have to use a distinct identifier for each cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"s%i-r%i", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
//you can customize your cell here because it will be used just for one row.
}
return cell;
}
First of all you have to give identifier to tableview cell then it will displays.
e.g.
NSString *cellIdentifier = [NSString stringWithFormat:#"%d_cell", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]];
}
return cell;
}
1.Drag TableView Controller in StoryBoard
2.Sele ct the TableView and in Right Inspector change number of Prototyes Cell(number of cells) and then Dynamic Prototypes to Static Cell
3.Customise the Cell according to your requirement
Tat's it Static TableView is created.Don't override any of tableview delegate or datasource methods
Below i added the screenshot of Right Inspector
Here's my code:
- (UITableView *)table {
if (!_table) {
_table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
[_table setDelegate:self];
[_table setDataSource:self];
[_table registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
return _table;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
else
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
The problem is when I registerClass for my table, it assumes that my cell style is UITableViewCellStyleDefault. So that's why detailTextLabel doesn't show up. I tested it.
Comment out the registerClass line doesn't work because I don't have any CellIdentifier for dequeueReusableCell. So it will throw some exceptions.
If I'm not using dequeue, it works, but it not the best practice.
AFAIK, table cell couldn't change its style after init. So how can I make the detailTextLabel show up ?
The problem is when I registerClass for my table, it assumes that my cell style is UITableViewCellStyleDefault. So that's why detailTextLabel doesn't show up
That is correct. The solution is: do not register UITableViewCell as your class. Register a custom UITableViewCell subclass whose sole purpose in life is that it initializes itself to a different style.
For example, register the MyCell class, which you have defined like this:
#interface MyCell:UITableViewCell
#end
#implementation MyCell
-(id)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:UITableViewCellStyleValue2 // or whatever style you want
reuseIdentifier:reuseIdentifier];
return self;
}
#end
I'm using custom cell like that:
PropertyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
and it's registered as:
[self.tableView registerNib:[UINib nibWithNibName:#"PropertyCell" bundle:nil] forCellReuseIdentifier:#"PropertyCell"];
Class is declared as:
#interface PropertyCell : UITableViewCell <UITextFieldDelegate>
It contains a UITextField in xib and I need to assign a delegate to it on init.
Problem is that:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
is never called in that scenario.
Which kind of initializer is used by that dequeueing mechanism ?
You are going to want to use initWithCoder or awakeFromNib as posted in this question...
initwithstyle:reuseIdentifier: not called
Make sure to init your cell in the UITableViewDataSource method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *PropertyCellIdentifier = #"PropertyCell";
PropertyCell *cell = [tableView dequeueReusableCellWithIdentifier: PropertyCellIdentifier];
if (!cell) {
cell = [[PropertyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: PropertyCellIdentifier];
}
// configure cell
return cell;
}
In XCode 5, when you add a UITableViewController with more than 1 prototype cell which all contain labels etc., the content is displayed because the UITableViewController automatically sets the data source and delegate of the table view and sends a reloadData message to it.
iOS Developer Library - Basics of Table View Creation
But when you drag a UITableView to a UIViewController I believe you have to create instance methods similar to the default ones below in order for the content to be reloaded and made visible.
My question is how can I target a UITableView somewhere within a UIViewController and set its data source and delegate and have it reloaded and its content displayed properly?
Here is the default code for the UITableViewController:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
return cell;
}
Here is my code that works with UITableViewController but not in UIViewController for the UITableView that it contains:
...
#property (nonatomic, strong) NSArray *menuItems;
...
- (void) viewDidLoad
{
[super viewDidLoad];
self.menuItems = #[#"rowOne", #"rowTwo", #"rowThree", #"rowFour"];
}
...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [self.menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
IN your code where u have created your cell if it not exists? And also make cell identifier as static.
You should create cell if it not exists in cellForRowAtINdexPath like as following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil)
{
//Create your cell
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Configure your cell
return cell;
}
You can set data source and delegate in a few ways. If you add table view to view controller in storyboard just control drag from table view to view controller and select delegate and do it again and select data source.
You can also create outlet and in your view controller in viewDidLoad do it by:
self.tableView.dataSource = self;
self.tableView.delegate = self;
The other way is create table view in code and add it to your view controller view. You can do it in viewDidLoad like that:
tableView = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_VIEW_FRAME) style:UITableViewStylePlain];
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
If you want to reload the data just call:
[self.tableView reloadData];
Hope this help.
Make sure you implement UITableViewDelegate and UITableViewDataSource protocols and set these in the initWithNibName or initWithCoder initializers.
This is how your .h file should look like:
#interface TestViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
Here is what you need to do in the .m file:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
return self;
}
if you are using storyboards, please use initWithCode as given below:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
return self;
}
You are only dequeuing the cell but you are not creating one if dequeueReusableCellWithIdentifier returns nil. You should implement in following way.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// here you can configure the cell
return cell
I have a Class MTTableViewCell : UITableViewCell
The init method in the class is as follows:
Notice that I set the backgroundcolor to purple.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
[self setBackgroundColor:[UIColor purpleColor]];
}
return self;
// return [self initMVTableViewCellWithStyle:style reuseIdentifier:reuseIdentifier cellColor:nil];
}
I call the following method from the delegate of the tableview
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* identifier = #"one";
[self.tableView registerClass:[MVTTableViewCell class] forCellReuseIdentifier:identifier];
MVTTableViewCell *cell = [[MVTTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.textLabel.text = [self->datasource objectAtIndex:[indexPath row]];
return cell;
}
However I do not see any change in the color of the table view cells.
What is going wrong ?
When I want to change the background color of my cell i usually use this:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
[self.contentView setBackgroundColor:[UIColor purpleColor]];
}
return self;
}
I would try moving your call to register class to your viewDidLoad method, and instead of alloc/initing the cell, try dequeueing one from the table. By registering the cell's class for reuse, you're preparing it for recycling by the table. Note: be sure that the cell id that you register is the same as the one that you access in cellForRowAtIndexPath:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[MVTTableViewCell class] forCellReuseIdentifier:#"one"];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"one";
MVTTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
cell.textLabel.text = [self->datasource objectAtIndex:[indexPath row]];
return cell;
}
Unfortunately I'm not on a machine where I can test this an I can't seem to remember the cell call structure in this case (it's late :)) But I would check to see if maybe a different init is being called, otherwise, try setting the background color in cellFor... itself just to troubleshoot. Try setting it on the contentView of the cell as well.
follow this... for custom tableview cell
UITableViewCell Space between Title and Subtitle -iOS
http://www.appcoda.com/customize-table-view-cells-for-uitableview/