How to set up a UITableViewCell style doing UITableViewController programmatically? - ios

I'm creating UITableViewController without a help from the Storyboard.
I've got the following code:
- (void)viewDidLoad {
[super viewDidLoad];
self.cellReuseIdentifier = #"myViewControllerCellReuseIdentifier";
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:self.cellReuseIdentifier];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellReuseIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:self.cellReuseIdentifier];
}
}
In this case the cell style is not there. How do I fix that?

I think if you just add the UITableView, set your viewcontroller as the delegate and datasource and that's enough. If you set a breakpoint in cellForRowAtIndexPath, does it trigger?
Not sure what you're doing with,
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:self.cellReuseIdentifier];
Rather do this,
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
Let me know if that's not what you're looking for, good luck.

Related

Programmatically creating custom cells in objective c?

I'm having issues getting customs cells to show up. Below I've posted a simplified version of my code:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
NSLog(#"Being Called?");
//reuseID = #"newtableid";
self.backgroundColor = [UIColor redColor];
self.name = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 50)];
self.name.backgroundColor = [UIColor redColor];
[self addSubview:self.name];
return self;
}
In my viewController, I set up the tableView in the ViewDidLoad method:
self.table = [[UITableView alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 400) style:UITableViewStylePlain];
self.table.delegate = self;
self.table.dataSource = self;
self.table.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.table];
[self.table registerClass:NewTableViewCell.class forCellReuseIdentifier:#"Cell"];
Then, I complete the cellForRowAt method like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"Cell";
NewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[NewTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.backgroundColor = [UIColor blackColor];
cell.name.text = [_familyDetails objectAtIndex:indexPath.row];
return cell;
}
The problem is, I don't get anything to show up on my cells. My NewTableVIewCell constructor is called, but the cells show up blank (without color, label, etc.) What am I doing wrong?
If you're creating the cell programatically, make sure you register your cell to your table view.
[self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:"yourCellId"];
I am using a generic UITableViewCell in this case. You can try to change the text label of it in cellForRowAtIndexPath to see whether that works.
Be sure to change it to your custom cell class if needed.
In order to dequeueReusableCellWithIdentifier, you have to use
- (void)registerClass:(Class)cellClass
forCellReuseIdentifier:(NSString *)identifier
and normally you will not even have to instantiate NewTableViewCell if you use dequeueReusableCellWithIdentifier:forIndexPath:. However, if you still use dequeueReusableCellWithIdentifier: then you still need to instantiate your cell subclass (thanks for reminding me Alejandro Ivan).
EDIT: So you have to write something like this, in your viewDidLoad for example :
- (void)viewDidLoad {
[super viewDidLoad];
// Your stuff...
[self.table registerClass:[NewTableViewCell class] forCellReuseIdentifier: simpleTableIdentifier];
}

Why is my custom UITableCell not displaying the text?

So I tried subclassing UITableViewCell to make a message cell, I've been testing it and I can't seem to get it to show anything. It's not the data source because it was working fine with I wasn't trying to use a custom cell. I'm not sure why nothing is appearing in the cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MessageCell * cell = (MessageCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil){
cell = [[MessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.messageContent.text = self.messages[indexPath.row][#"content"];
return (UITableViewCell*) cell;
}
this is the init method i have in the subclass of UITableViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self){
//I played with the CGRect numbers but that's not it.
messageContent = [[UILabel alloc]initWithFrame:CGRectMake(3,35, 200,30)];
messageContent.textColor = [UIColor redColor];
messageContent.backgroundColor = [UIColor whiteColor];
messageContent.highlightedTextColor = [UIColor clearColor];
messageContent.adjustsFontSizeToFitWidth = YES;
[self.contentView addSubview:messageContent];
}
return self
}
1st check using below line :
cell.messageContent.text = #"asdfasdf";
If it's work properly than something wrong in
self.messages[indexPath.row][#"content"]
line . . .
If you are using storyboard, the method -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; most definitely wont get called.
Add this method to MessageCell.h:
- (void)setupCellWithText:(NSString *)text
Add the implementation to MessageCell.m:
- (void)setupCellWithText:(NSString *)text{
messageContent = [[UILabel alloc]initWithFrame:CGRectMake(3,35, 200,30)];
messageContent.textColor = [UIColor redColor];
messageContent.backgroundColor = [UIColor whiteColor];
messageContent.highlightedTextColor = [UIColor clearColor];
messageContent.adjustsFontSizeToFitWidth = YES;
[self.contentView addSubview:messageContent];
messageContent.text = text;
}
Now modify your delegate method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MessageCell * cell = (MessageCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil){
cell = [[MessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
[cell setupWithText:[self.messages[indexPath.row][#"content"]]];
return (UITableViewCell*) cell;
}
Hope this helps. Sorry for typos.
When you create a custom UITableViewCell your tableView needs to know about it. Here's how. This goes in the UITableViewController's viewDidLoad:
[self.tableView registerClass:[MessageCell class] forCellWithReuseIdentifier:#"cell"];
Now your tableViews knows about your class and no more casting is necessary.
Bonus tip! You don't need this:
if(cell == nil){
cell = [[MessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
dequeueReusableCellWithIdentifier already does that for you.
Here's what the whole thing would look like.
- (void)viewDidLoad {
[super viewDidLoad];
// Register custom cell for table view
[self.tableView registerClass:[MessageCell class] forCellWithReuseIdentifier:#"cell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.messageContent.text = self.messages[indexPath.row][#"content"];
return cell;
}
** I just wrote this in the browser so forgive my errors
Check set your UITableViewDelegate and UITableViewDataSource.
On Xib: See image below.
Or in ViewDidLoad:
self.mTableView.delegate = self;
self.mTableView.dataSource = self;
Hope this helps!

UITableView data is not showing

I created a custom class ("customClass") that is a subclass of UIView. I then added a tableView to it's subview, and created an array for the datasoucre. I set the delegate and datasource to self. Then in the storyboard, I set a UIViews class to customClass.
Then in the mainVC class, I set an array to some strings and set that array to the array in the customClass. When I run the app, it doesn't crash or give me any errors, but I don't see any results in the tableView
Here's how it's setup in mainVC.m:
self.myArray = [[NSArray alloc] initWithObjects:#"First", #"Second", #"Third", #"Fourth", #"Fith", #"Sixths", #"Seventh", nil];
self.myView.resultArray = self.myArray;
[self.myView.tableView reloadData];
Here is the code in customClass:
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
[self setupTableView];
}
return self;
}
- (void)setupTableView
{
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain];
[self addSubview:self.tableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.resultArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
[cell.textLabel setText:self.resultArray [indexPath.row]];
return cell;
}
When I run the app, I don't see any results in the tableView although I do see a tableView shown. What am I doing wrong, and how can I fix it?
Edit
Just realized, cellForRow doesn't even get called! I did a reloadData, and it still didn't get called.
initWithFrame: - It is recommended that you implement this method. You
can also implement custom initialization methods in addition to, or
instead of, this method.
initWithCoder: - Implement this method if you load your view from an
Interface Builder nib file and your view requires custom
initialization.
initWithCoder is called much before init and viewDidLoad methods
In MainVC
viewClass *vc = [[viewClass alloc] initWithFrame:self.view.frame];
vc.resultArray = [[NSArray alloc] initWithObjects:#"First", #"Second", #"Third", #"Fourth", #"Fith", #"Sixths", #"Seventh", nil];
[vc.tableView reloadData];
[self.view addSubview:vc];
In Custom Class...
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setupTableView];
}
return self;
}
- (void)setupTableView
{
self.tableView = [[UITableView alloc] initWithFrame:self.frame style:UITableViewStylePlain];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
[self addSubview:self.tableView]; // Datasource and delegate after alloc init
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.resultArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
[cell.textLabel setText:self.resultArray [indexPath.row]];
return cell;
}
Register Cell when using Custom UItableviewCell, Otherwise don't use [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];, it will crash.
You can set customClass's backgroundColor to red,and then check the customClass is added on the mainVC's view.

UITableViewCell detailTextLabel doesn't show up even with different cell styles

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

Trying to add a Tableview inside of a UIView. What am I doing wrong here?

I'm not sure how to approach this. I'm loading a separate table view controller nib file to my viewcontroller. How do I position it the way I want? Also, Is the below query all I need, or am I missing something? It keeps crashing on me.
- (void)viewDidLoad
{
[super viewDidLoad];
HSTableViewController *tableViews = [[HSTableViewController alloc]initWithNibName:#"HSTableViewController" bundle:nil];
[self addChildViewController:tableViews];
tableViews.view.frame = CGRectMake(0, 0, 100, 100);
//tableViews.view.frame = self.view.bounds;
[self.view addSubview:tableViews.view];
[tableViews didMoveToParentViewController:self];
To add a tableview in code to a view controller wherein that VC will act as both the data source and delegate you would do the following.
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.textLabel.text = #"Hello World";
return cell;
}
And then in your .H file you need to inform the program that you're going to act as both the Delegate and DataSource
#interface NSSViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
From what I gathered out of your question, that should get you where you need to go. I will edit accordingly if you require further assistance.
Set your UITableView's frame in -viewWillAppear: like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
tableViews.view.frame = self.view.bounds;
}
If anyone else needs this. See this tutorial I found on youtube that helped a lot. Thanks for all the help.
http://www.youtube.com/watch?v=DzedmcFlm1c

Resources