Table view inside a normal view controller - ios

I'm doing this iPhone project where I need to have a (dynamic) table view inside a normal view controller. I didn't choose a Table View Controller because I need to put other stuff in the page. Imagine a page with text fields, buttons and my small table view of about 4-5 cells.
When I run the app, I need to touch a button to segue to this view. The I click the button, the app crashes and tells me that:
2012-07-22 14:40:57.304 How Many?[3055:f803] * Assertion failure in
-[UITableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:6061
This is my .H file:
#import <UIKit/UIKit.h>
#interface ProjectViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#end
This is my .M file:
#import "ProjectViewController.h"
#interface ProjectViewController ()
#end
#implementation ProjectViewController
//MyViewController.m
#pragma mark - Table View Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"numberOfSectionsInTableView");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"numberOfRowsInSection");
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cellForRowAtIndexPath");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
NSLog(#"cellForRowAtIndexPath");
cell.textLabel.text = #"Test";
return cell;
}
#end
I control-dragged from the table view to my controller to set the delegate and the datasource.
What did I do wrong??
Thanks for your help.

Try to make an outlet in your .h file and wire it to the tableView in your storyboard
ProjectViewController.h
#property (nonatomic, strong) IBOutlet UITableView *myTableView;
ProjectViewController.m
#synthesize myTableView;
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cellForRowAtIndexPath");
UITableViewCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:#"cell"];
NSLog(#"cellForRowAtIndexPath");
cell.textLabel.text = #"Test";
return cell;
}

In your -cellForRowAtIndexPath, if you do this, you will be fine.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cellForRowAtIndexPath");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
}
NSLog(#"cellForRowAtIndexPath");
cell.textLabel.text = #"Test";
return cell;
}
The problem is your cell never got memory allocated and initialized. That's why you get the error.

Related

How to display swipe button in uitableviewcell by tap on cell?

I have tried to call the functions manually by programming, those functions are
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
When i call the functions it works inside the functions for example the editActionsForRowAtIndexPath function but doesnt show the button.
Any clue or help will be highly appreciated.
Did you forgot to call [self.tableView setEditing:YES animated:YES]; ?
Why do you use above 3 methods for swipe and deleting the table view cell?
Only one method is enough for doing this.I created sample one for your question.It works fine.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *tableViewEdit;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController (){
NSMutableArray *arr;
}
#end
#implementation ViewController
#synthesize tableViewEdit;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arr = [[NSMutableArray alloc]initWithObjects:#"iOS",#"Android",#"Windows",nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//UITableViewDataSource methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return arr.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableViewEdit dequeueReusableCellWithIdentifier:strCell];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
cell.textLabel.text = arr[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete)
{
[arr removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
When I run the application first it shows the below data
Then when I swipe the table view
Finally I delete the data from the table view and the table view

Custom Cells are created, but not displayed

So I've used this tutorial to populate a UITableView with custom cells that represent balances. When stepping through the code, I witness the correct amount of cells get created (only 4 with the current test data) and their labels' text set correspondingly.
My problem is when the table is displayed on the screen, only the first row/cell is displayed.
Any insight as to why this could be occurring would be greatly appreciated!
Removed old code.
BalanceCell.h:
#import <UIKit/UIKit.h>
#interface BalanceCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#property (weak, nonatomic) IBOutlet UILabel *amountLabel;
#property (weak, nonatomic) IBOutlet UILabel *modifiedLabel;
#end
EDIT:
My TableView delegate methods are now as follows:
- (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 [_balances count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
BalanceCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[BalanceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [_hex colorWithHexString:_themeColourString];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(BalanceCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
Balance *item = [_balances objectAtIndex:indexPath.row];
cell.nameLabel.textColor = _themeColour;
cell.nameLabel.text = item.name;
cell.amountLabel.textColor = _themeColour;
cell.amountLabel.text = [NSString stringWithFormat:#"%#%#", item.symbol, item.value];
cell.modifiedLabel.textColor = _themeColour;
cell.modifiedLabel.text = [NSString stringWithFormat:#"%#", item.modified];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 94;
}
As #Sebyddd suggested, I now register the NIB in the viewDidLoad method.
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"BalanceCell" bundle:nil] forCellReuseIdentifier:#"Cell"];
}
These changes may make my code more correct but still only the first cell is displayed.
If cells are getting created and returned properly I guess height is not being set propery. By default I beleive all cells have a height of 44. If your cell exceeds this height it might not get displayed.
You can tell the tableview to adjust height for every cell using (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath delegate
In that delegate just return your cells height.
EDIT:
You are using dequeueReusableCellWithIdentifier: which will return A UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.
Instead use dequeueReusableCellWithIdentifier:forIndexPath: which will return A UITableViewCell object with the associated reuse identifier. This method always returns a valid cell.
You need to register the nib/class for that custom cell in viewDidLoad
Try this:
if (cell == nil) {
[tableView registerNib:[UINib nibWithNibName:#"BalanceCell" bundle:nil] forCellReuseIdentifier:#"Cell"];
cell = [[BalanceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
Use this tuto : http://www.appcoda.com/uitableview-tutorial-storyboard-xcode5/ , your tuto is a bit outdated, and hard to follow !

UITableView crashing when selecting row

When I click on a cell in my tableview, the app crashes with:
// QuestionViewController.h
#interface QuestionViewController : UIViewController <UITableViewDelegate , UITableViewDataSource> {
}
#property (nonatomic, strong) AppDelegate *app;
#property (nonatomic, retain) PFObject *feed;
#end
// QuestionViewController.m
#synthesize app, feed;
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [[feed objectForKey:#"options"] count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *cellTxt = [[[feed objectForKey:#"options"] objectAtIndex:indexPath.row] objectForKey:#"option_text"];
[[cell textLabel] setText:cellTxt];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"clicked cell");
}
- (void)viewDidLoad {
[super viewDidLoad];
app = [[UIApplication sharedApplication]delegate];
feed = [app.feed objectAtIndex:0];
}
I have implemented didSelectRowAtIndexPath, but it doesn't get called before crashing.
Other threads on SO suggest that I have unconnected outlets but I have checked that this isn't the case.
I am creating multiple instances of the above UIViewController like this:
for (int a = 0; a < totalQuestions; a++) {
QuestionViewController *temp = (QuestionViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"aQuestion"];
temp.view.frame = CGRectMake(self.view.frame.size.width*a+scrollWidthBeforeAppend, 0, 320, 443);
[scroller addSubview:temp.view];
}
And adding them to a scroll view. They display correctly, the UITableView is populated, and everything seems to work fine other than when I try and click on a cell. Any suggestions?
Your temp UIViewControllers get deallocated by the time you press a cell.
You should keep a reference to them to prevent this, for example in an array.

Exception at cellForRowAtIndexPath function - UITableView

I want to display a list of data on "UITableView".
When I run the code I get the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:
'unable to dequeue a cell with identifier Cell - must register a nib or a class for the
identifier or connect a prototype cell in a storyboard'
I get the error given above when I run the code below. The error is thrown at the
cellForRowAtIndexPath function. How can I solve this error?
#interface TheViewController ()
#property (strong, nonatomic) NSMutableArray *myTData;
#property (weak, nonatomic) IBOutlet UITableView *tableViewOutlet;
#end
#implementation TheViewController
- (void)viewDidLoad
{
self.tableViewOutlet.delegate = self;
self.tableViewOutlet.dataSource = self;
self.tableViewOutlet.scrollEnabled = YES;
self.myData = [[NSMutableArray alloc] initWithObjects:#"obj1", #"obj2", nil];
[self.tableViewOutlet reloadData];
[super viewDidLoad];
}
#pragma mark UITableViewDataSource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return myData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"hede"];
}
[cell.textLabel setText: [myData objectAtIndex:indexPath.row]];
[cell.detailTextLabel setText:#"hede hodo"];
//
// Configure the cell..
return cell;
}
#pragma mark UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
#end
The exception is exactly what it says it is.
In iOS 5, you would call [tableView dequeueReusableCellWithIdentifier:CellIdentifier] and if it didn't return one, you would create one. The new call -dequeueReusableCellWithIdentifier:forIndexPath: should have a NIB or cell class registered and it will then always succeed.
You should call either
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
or
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier
in your -viewDidLoad method.
In your storyboard, select the prototype cell, go to inspector and give the cell the identifier "Cell" or whatever you want as long as you have the same here : static NSString *CellIdentifier = #"Cell";

simple TableView not displaying data

I am a beginner, learning how to do tableViews. I followed everything in my book, but my table View is not being populated. Shouldn't it display the word "Testing" for three rows here? My tableview Outlet is connected, and I enabled the delegate and datasource. What am I missing here? After all, I am following a book.
#pragma mark UITableViewDataSource Methods
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"cell"];
if( nil == cell)
{
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = #"Testing";
return cell;
}
-(NSInteger)tableView: (UITableView *)tv numberofRowsInSection:(NSInteger)section
{
return 3;
}
#pragma mark UITableViewDelegate Methods
-(void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tv deselectRowAtIndexPath:indexPath animated:YES];
}
here is my .h file
#import <UIKit/UIKit.h>
#interface CLViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
You have a typo in your data source method, numberofRowsInSection should be
numberOfRowsInSection.
As a consequence, the default implementation of numberOfRowsInSection is called and
that returns 0.

Resources