Custom UITableViewCell in storyboard won't load - ios

I'm facing a strange problem. I have an iOS 7.1 storyboard app with a UITableViewController using Xcode 5. I created a subclass of UITableViewCell and set it as the class for the cell from the IB and also added a cell identifier. The style is set to Custom as well. I haven't made any modifications to this subclass yet though. It has only the template code you get when you create a new class.
In the table view controller I have this code. Just setting the data source and the delegate methods.
#import "TableViewController.h"
#import "TextFieldTableViewCell.h"
#interface TableViewController ()
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
TextFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.text = #"hello world";
return cell;
}
In the cellForRowAtIndexPath, I simply set a value to the textLabel property of the cell. Even that doesn't get shown up. I double checked the identifier, style and everything bit they are all set.
I have no idea why this isn't working. I also checked out a few online tutorials on this subject matter like this one but I have everything as they've described.
Can anyone please tell me if I'm missing anything?
I've uploaded a test project to my Dropbox here if you want to take a quick look at it.

Found it! You've overridden the layoutSubviews of TextFieldTableViewCell class, and wrote nothing inside of it.
Just remove the layoutSubviews (for now) and it will work.
Update: A better solution;
- (void) layoutSubviews
{
[super layoutSubviews];
}

Related

How to achieve "dequeueReusableCellWithIdentifier"

sorry, I wanna to know that apple's underlying code implementation
In storyboards you can set identifier of each of the cells you put inside the table view by setting any text to Identifier field:
The text in your code must be exactly the same, case sensitive to use it.
There are also ways of doing this programmatically to register a cell on table view before using it (setting it in viewDidLoad should be enough).
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:#"MyTableViewCellIdentifier"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:#"MyTableViewCellIdentifier"];
return myCell;
}

TableView in a TableViewCell

I want to put a tableview into a tableview cell. I like the formatted look it gives. I'm hoping to put in a few fields, for like name, email, etc. What am I missing to be able to make this work? Currently I can not set "ProfileCell" as the tableview class.
In my .h file of the profile cell I added:
#interface ProfileCell : UITableViewCell <UITableViewDataSource,UITableViewDelegate>
and in my .m file I added some basic methods for the tableview:
#import "ProfileCell.h"
#implementation ProfileCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of time zones in the region for the specified section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Doing this");
static NSString *MyIdentifier = #"MyReuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
return cell;
}
#end
EDIT:
I have seperated the code for the cellview tableview into it's own files, and linked tableview to this class, however it does not fire when viewed:
#interface ProfileBasicDetails : UITableView <UITableViewDataSource,UITableViewDelegate>
Per comments below
This is what my page should look like when said and done. It's so users can enter in their details, while looking nice and formatted, but not ghetto looking.
I'm assuming you've embedded the UITableView into the cell?
You should wire the tableview to an outlet in the cell. Then set the delegate on the tableview in your awakeFromNib method.
*As vikingosegundo mentioned in the comments, this is potentially a pretty fragile approach.

How do I add storyboard-based Header and CustomTableCell to a “Search Bar and Search Display Controller”

PRESENTATION
Mine is a simple project: It consists of a NavigationController, ViewController, and a “Search Bar and Search Display Controller”
My .h file is
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate>
#end
and my .m file is
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic,strong)NSMutableArray *data;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
self.data=[[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [_data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"Row %d: %#", indexPath.row, [_data objectAtIndex:indexPath.row]];
return cell;
}
#pragma mark - delegate
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(mockSearch:) userInfo:searchString repeats:NO];
return NO;
}
- (void)mockSearch:(NSTimer*)timer
{
[_data removeAllObjects];
int count = 1 + random() % 20;
for (int i = 0; i < count; i++) {
[_data addObject:timer.userInfo];
}
[self.searchDisplayController.searchResultsTableView reloadData];
}
#end
And that’s the entire program. What does it do? User makes a search and the data is displayed in a TableView (similar to a google search).
PROBLEM
I need to use a CustomTableViewCell for my table. And I need to build the TableViewCell from the storyboard (easy to visualize). I am stuck with the storyboard part. How do I place a TableViewCell on the storyboard without a TableView to place it in? I had an idea, I tried it, but it didn’t work. Here is what I did. I placed a “never-to-be-used” TableViewController in the storyboard whose sole purpose is to hold my CustomTableViewCell. Then in code I subclass TableViewCell and use IBOutlet to link the sub-views of the storyboard TableViewCell to my CustomTableViewCell . And then I used my cell as CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];. This didn’t work. The tableView remained blank. And my guess for the failure is that CustomTableViewCell does not belong to the tableView being dequeued from.
I need the UISearchBar to always stay inside the NavigationBar. But so far self.searchDisplayController.displaysSearchBarInNavigationBar = YES; is not doing it. When I first start the app the searchBar is inside the NavigationBar. But as soon as I click on it, it smacks itself right in the middle of my scene/screen and never leaves.
I need to add a Header to my TableView. Which I thought of doing the same way as the CustomTableViewCell, but with a UIView parent class. But again, the CustomTableViewCell portion failed.
PLEA
Thank you for any help you can provide me.
UPDATE
All I am trying to do is allow my users to launch a server side search and view the results in a tableView. This is such a basic thing, I image many people here have done this a number of times. Being new to iOS, I am stuck. But at this point, I have posted my entire project (anyone can reconstruct it), and I have explained in details all the ways I tried to solve the problem. So if someone has a sample project they don’t mind sharing, it would help very much. Or if you know of a git project please put a link to it. Thanks.
If you want to make a stand-alone view (not in a view controller) in IB, then you should do it in a xib file, not a storyboard. You can have as many storyboard and xib files in an app as you want; they can be mixed freely. To make a new cell in a xib file, just go to New File --> User Interface --> Empty then drag in a UITableViewCell. Add any subviews you want, and in your table view controller (or whatever class is your table view data source), register the xib file with, registerNib:forIdentifier: (usually, you do this in viewDidLoad).

Customizing uitableviewcell when using storyboards

I'm doing my project with storyboards and I'm trying to implement a custom UITableViewCell.
I would like to do the following in my custom cell:
#import "CustomCell.h"
#implementation CustomCell
#synthesize myLabel, myButton;
- (instancetype)initWithCoder:(NSCoder *)decoder
{
if ((self = [super initWithCoder:decoder]))
{
//want to custom setup of properties placed in the cell
self.myButton.backgroundColor = [UIColor redColor];//this does NOT work
//and so forth...
}
return self;
}
But the background color is not set. It only works when I set the background color of the button in the tableViewController's cellForRowAtIndexPath function, like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
MyObject *obj = self.myObjects[indexPath.row];
cell.myButton.backgroundColor = [UIColor redColor];//This works!
cell.myLabel.text = obj.name;
return cell;
}
And I have trying debugging by setting break points and NSLog and the initWithCoder gets called before cellForRowAtIndexPath for every cell??
But the background color of the button in the cell does not show when I set it in the custom cell.
Can any help?
Try using the awakeFromNib method instead of initWithCoder: to do any initial customization of the cell. And as mentioned in comments, for simple things like background colors of controls, you can probably just do that in Xcode via the storyboard.

Fails to call delegate/datasource methods in UITableView implementation

I have created .h and .m files for UITableView called mainTableViewgm.h and mainTableViewgm.m resp. and I am calling -initWithFrame: method from my main view controller to this mainTableViewgm.m implementation file
[[mainTableViewgm alloc]initWithFrame:tableViewOne.frame]
Note that this tableview is in my main view controller. But I have created separate files for the tableView and have also set the custom class to mainTableViewgm in storyboard.
the -initWithFrame: methods appears as follows
- (id)initWithFrame:(CGRect)frame
{
//NSLog(#"kource data");
self = [super initWithFrame:frame];
if (self)
{
[self setDelegate:self];
[self setDataSource:self];
[self tableView:self cellForRowAtIndexPath:0];
[self tableView:self numberOfRowsInSection:1];
// Initialization code
}
return self;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"kource data");
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"kource data2");
UITableViewCell*cellOne =[[UITableViewCell alloc]init];
cellOne.detailTextLabel.text=#"text did appear";
return cellOne;
}
the -initWithFrame: is being called fine along with the 'if (self)' block in this method. But the problem is numberOfRowsInSection: and cellForRowAtIndexPath: are not being automatically called here . kource data/kource data2 never appear in log. What do I do to load the table? Are the delegate/datasource being set incorrectly?
I must mention that I have also set the UITableViewDelegate and UITableviewDataSource protocols:
#interface mainTableViewgm : UITableView <UITableViewDelegate,UITableViewDataSource>
#end
Help will be much appreciated. Thank you.
Your tableview is not loaded when the controller is initializing, so you cannot do that in the init methods. You have to move your code to the viewDidLoad method.
Also you are not setting the delegate and datasource on the tableview object (probably a type, you are setting them on the view controller). It should look like this:
- (void)viewDidLoad:(BOOL)animated {
[super viewDidLoad:animated];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self]; // <- This will trigger the tableview to (re)load it's data
}
Next thing is to implement the UITableViewDataSource methods correctly. UITableViewCell *cellOne =[[UITableViewCell alloc] init]; is not returning a valid cell object. You should use at least initWithStyle:. And take a look how to use dequeueReusableCellWithIdentifier:forIndexPath:. A typical implementation would look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// Reuse/create cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Update cell contents
cell.textLabel.text = #"Your text here";
cell.detailTextLabel.text=#"text did appear";
return cell;
}
I can't believe I've been doing XCode programming for two years, and still hit this issue.
I had the same problem with XCode 6.1 - I was setting my UITableView's delegate & dataSource in the viewWillAppear function, but none of the delegate functions were kicking in.
However, if I right-clicked on the UITableView on the Storyboard, the circles for delegate and dataSource were empty.
The solution, then, is to hold down the CTRL key, and drag from each of these circles up to the name of your UIView which contains your UITableView:
After doing this, my UITableView happily populated itself.
(So, we're upto v6.1 of XCode now are we ? Do you think Apple ever going to make this thing, you know, friendly...? I would quite like to add a Bookmark in my code... that'd be a nice feature.)

Resources