i ve upgrated to iOS 5 with XCode 4.2 version.
since i ve upgraded i'm not able to create proper workign table view controller.
1) Table view is shown on the device, but when i try to scroll up, it crashes without any error message
2) when i try to select a cell , didSelectRowAtIndexPath is not called.
NOTE: the same code was workign for me before upgrating to iOS5.
This is the code for TableViewController.m file
#import "CTableViewController.h"
#implementation CTableViewController
#synthesize arrNames;
-(id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
NSLog(#"CTableViewController::initWithStyle");
// Custom initialization
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
arrNames = [[NSMutableArray alloc]initWithObjects:#"Peter Frank Brauer",#"Robert Schneider",#"Winfried Walter Kem",#"Eugen Germen Bachle",#"Clara Weib",#"Heinz Guther Winkler",#"Roland Bendel",#"Swen Aschemeyer",#"Patrick Bodingmeier",nil];
}
-(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.arrNames count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.textLabel.text = [self.arrNames objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:16];
NSLog(#"CTableViewController::cellForRowAtIndexPath");
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"called didSelectRow method");
}
#end
Thank you, Please help
Suse
If it's crashing without any error message than it's probably a memory management issue and it is likely to happen because of some other part of the code, or even because a wrongly formatted nslog.
The compiler doesn't seem to notice a few obvious things like setting a fraction value for an int which will crash the app in an instant but without any meaningful error message.
Try to look for mundane things in your code and not just in the tableView implementation.
Also, is there any specific reason your are populating your arrNames with alloc,init (non-autorelease) instead of arrayWithObjects?
Also: Run the static analyzer! It may help. Keep the Run button pressed and an Analyze button will pop up.
I copy and pasted your source code into a fresh project. A few things jumped out at me.
You are subclassing UITableViewController. Try just subclassing UIViewController, and delete your initWithStyle method.
Make sure that in the nib, the tableview delegate and datasource are both attached to File's Owner.
If you are still experiencing crashes, then this code is NOT your problem.
How you can select a row if is crashing first?
By the way,the code seems to be not the problem.
Try this after restarting your Xcode:
Go to Organizer
Select the Project tab
Click on your opened project and DELETE Derived data.
Then wait for the re-indexing. (You can see the top bar loding and the code with new index target).
So like usual Clean All Target and Build.
It works for me in similar cases.
Hope it help.
in My case it was controller instance declared locally and it was losing delegade so i declared instance in header and everything works.
Related
I'm working on a project that parse data from web service and shows in a table view. Everything is ok, but I'm not satisfied with the performance of tableview. After parsing data form web I called reload data to show the data, But it is not showing cells immediately. It shows the data after 10/15 seconds later. I've checked all data's are loaded before I called reload data. And the strange thing is that it shows the cells immediately if I try to drag the table.
Any idea?
Update
-(void)receivedCategories:(NSMutableArray *)categoryItems{
[self.spinner stopAnimating];
self.categories=categoryItems;
if (self.tableView!=nil) {
[self.tableView reloadData];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.categories count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CategoryCell";
CategoryCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.category = [self.categories objectAtIndex:indexPath.row];
return cell;
}
CategoryCell.m
#implementation CategoryCell
- (void)setCategory:(Category *)category
{
[self.categoryTitle setText:category.title ];
[self.categorySubTitle setText:category.description];
}
#end
It seems you're not calling [self.tableView reloadData]; from the main thread and that could be the cause of your problem.
You could try:
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
Also check the accepted answer here for more info.
I had the same problem, the time lag between [tableview reloaddata] and the app calling the method [cellForRowAtIndexPath] was too long (a couple of seconds). Putting the [reloaddata] method inside a dispatch_async(dispatch_get_main_queue(), ^{} solved the issue.
Are you using custom fonts?
I had a very similar problem, where my UITableView was taking considerably long to load. I finally found the solution, and it didn't had anything to do with my code or the way I was loading custom cells.
The problem occurred at run time, when the system loaded my custom UITableViewCells (with predefined custom fonts) from the storyboard, and because the custom fonts where not correctly installed, the system would look all over the place for the font files, causing a considerable lag when loading the file.
To make sure your fonts are correctly installed:
Include your fonts in your XCode project
Make sure that they’re included in the target
Double check that your fonts are included as Resources in your bundle
Include your iOS custom fonts in your application plist
Find the name of the font (To find out the correct name, you can print all installed fonts)
for (NSString* family in [UIFont familyNames]){
NSLog(#"Family %#", family);
for (NSString* name in [UIFont fontNamesForFamilyName: family]){
NSLog(#"\t Font%#", name);
}
}
Use UIFont and specify the name of the font
[UIFont fontWithName:#"FONT_NAME" size:size];
With the amount of code you are showing (none), I would have to say that the performance hit you are having is because you are calling reloadData with a very large number of records, or because you are doing some time consuming parsing/calculation when creating the cell. Also, If you are showing images on those cells, that might also cause performance problems.
When you create CategoryCell? In first time dequeueReusableCell will return nil. So then make the Category cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CategoryCell";
CategoryCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[CategoryCell alloc] init] autorelease]; }
cell.category = [self.categories objectAtIndex:indexPath.row];
return cell;
}
I'm new to iOS dev, so I do apologise for asking potentially dumb question.
What I want to do is something very similar to the default Weather app; where the app has a info button, it flips to another view which has a table along with a Done button to go back to the app.
I'm using the 'Utility Application' template which does most of this for me :)
However, I am now struggling to add a tableview into the flipview. Am I on the right path? I'm using storyboard at the moment - beginning to realise this is most likely a limitation on the GUI (after all a GUI can only go so far). If so, is this possible programatically and how would I go about applying it on a default 'Utility Application' template.
I'm using Xcode 4.2.
Any help would be appreciated. Thanks in advance :)
First of all, you'll want to drag and drop a UITableView onto your flipsideViewController in interface builder. Make sure that you like its delegate and data source to the view controller.
Then change flipsideViewController.h to create an instance variable for the array that will store the text for the cells labels and for the controller to conform to the tables delegate and data source methods.
#interface FlipsideViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArrayOfItems;
}
In flipsideViewController.m alloc/init and populate your array in viewDidLoad
myArrayOfItems = [[NSArray alloc] initWithObjects:#"firstItem",#"secondItem",#"thirdItem",#"fourthItem", nil];
And finally, copy and paste the following and you should have a working table!
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArrayOfItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myArrayOfItems objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected cell index:%i",indexPath.row);
}
I'm stuck with a seemingly very simple app that I'm trying to develop
Basically, I have a UITable, and two buttons: red/blue
When a button is pressed, a row with corresponding title of that button is append to the table
I'm overwhelmed by how complicated UITableView has to be implemented (datasource, delegate, resuable identifier, etc)
Can anyone help me out with this, preferably show me detailed codes
For my Buttons, I have something like this
- (IBAction)buttonPressed:(UIButton *)sender{
NSString *item = sender.currentTitle;
[self.cellArray addObject:item];
[self.myTable reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.cellArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"The Table Cell";
self.myTableCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (self.myTableCell == nil) {
self.myTableCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
self.myTableCell.textLabel.text = [self.cellArray objectAtIndex:indexPath.row];
return self.myTableCell;
}
Since you are learning this..i will post a simple solution.
Make add a member variable NSMutableArray *cellArrays;
initialize it in your viewDidLoad
in buttonPressed check;
if([#"red" isEqualToString:[YourButton titleForState:UIControlStateNormal]])
{
[self.cellArrays addObject:#"red"];
}
else
{
[self.cellArrays addObject:#"blue"];
}
[self.YOURTABLEVIEW reloadData];
Now in your table view datasource method
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.cellArrays.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//in between your code;
YOURCELL.textlabel.text = [self.cellArrays objectAtIndex : indexpath.row];
}
Try this ..
I'd recommend subclassing UITableViewController, then override the dataSource and delegate methods and you should be good to go. Going straight to UITableView is more complicated without any obvious benefits.
You may not be using Core Data, but I still recommend this lecture because it hooks up a TableViewController and works great - all code included. Check it out:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/node/289
The lectures in iTunes U explain everything further.
Enjoy,
Damien
I wanted to add that "One more thing, the compiler shows a warning says no reusable identifier. what exactly is that?" above...
His answer is correct, but to get rid of that compiler warning...
The tableviewcell of your tableview has to have an identifier. In IOS 5, in your storyboard, highlight the TableViewCell in your TableView, and enter a value in the Identifier. This must match the value in your code of the cell that you are creating.
This is either an XCode bug, or me missing a crucial rule here.
Update:
- What's the chance of this being a weird bug in XCode/Storyboard?
Situation:
iOS 5, Storyboard
This is the storyboard setup: http://i.imgur.com/T5WyD.png
Another screenshot of the full setup: http://i.imgur.com/1tVuz.png
TableViewController with Custom Cell, cell has reusable identifier "NewCell"
in "cellForRowAtIndexPath" I basically have:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewCell"];
return cell;
This throws an exception:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
Things I have already tried:
I setup a new project from scratch, TabBarController, with a TableViewController and a Custom Cell, all wired up in Storyboard, set a reusable cell identifier. Used the same code as above, worked perfectly. I don't know why it didn't work with the storyboard above...
I have a feeling it has something to do with the tree I built there, which is a TabBarController, loading a NavigationController, loading a TableViewController, providing a few items, one is clicked, which loads another TableViewController, which is unable to work with the custom cell, somehow.
Important:
- The issue is that the Storyboard should make sure that:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewCell"]; will never return NIL (unlike without the Storyboard/iOS4). But, mine is nil. And I can't, for the hell of it, figure out what's happening.
Heyo, I just had this problem today and figured out a few possible causes. To link a UITableView as a subview of a ViewController in Story board check that you have done these steps.
In your "ViewController.h", add <UITableViewDataSource> to your list
of protocols
#interface ViewController : UIViewController
<UITableViewDataSource>
you might want to add <UITableViewDelegate> as well but I didn't.
In your "ViewController.m" set up your Table view data source
functions
#pragma mark - Table view data source
- (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 [yourCells count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NewCell *cell = (NewCell *)[tableView
dequeueReusableCellWithIdentifier:#"NewCell"];
if (cell == nil) {
NSLog(#"Cell is NIL");
cell = [[CustomCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
return cell;
}
In Storyboard, connect the UITableView's "Data Source" and
"Delegate" references to the ViewController.
In Storyboard, give the Prototype Cell the Identifier "NewCell"
If these are done, I believe it should work.
Hope this helps =)
I always use custom cells in the storyboard like this:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
Make sure the number of rows/sections is at least one. And another thing to check is that you set the UITableViewController to your custom class name in the storyboard.
Did you double check the cell prototype identifier is "NewCell"?
Your setup as Tabbar->navigationcontroller->tableview is perfectly fine. I
am using this layout all the time.
verify also there's no useless runtime attributes anywhere in this
viewcontroller/tableview/cell.
your prototype looks a bit weird there - you added a UIButton to the cell as subview? why?
To solve this problem add the following just above your dequeueReusableCellWithIdentifier statement:
static NSString *CellIdentifier = #"NewCell";
making sure the identifier matches the prototype cell in Storyboard
It maybe late to answer this but i bet this will fix all your problems
I have one last problem that is killing me.
I am playing around with an older project which used the tableView:accessoryTypeForRowWithIndexPath method, of which i am trying to rewrite the app without it.
I have deleted the tableView:accessoryTypeForRowWithIndexPath method, but my solution isnt working just yet.
The problem is that now when I press the 'Edit' button on my DetailViewController View, the 'editing' accessory types dont show.
Below is my actual code, and I have also included the project file for this, because I am desperate for a solution that works.
My question is, what code do I have to change, to get the accessory to change, and no other effects. (I know the RootViewController works, but how can i get the DetailViewController table to do the same?)
Regards, #norskben
Project File Download: Get it here.
setEditing
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.navigationItem setHidesBackButton:editing animated:animated];
[tableView reloadData];
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.editingAccessoryType = UITableViewCellAccessoryCheckmark;
}
switch(indexPath.section) {
case 0:
cell.textLabel.text = coffeeObj.coffeeName;
break;
case 1:
cell.textLabel.text = [NSString stringWithFormat:#"%#", coffeeObj.price];
break;
}
return cell;
}
Project File Download: Get it here.
In your setEditing:animated: method you are doing two things that you are really not supposed to do. Reloading the table data there makes no sense. And if you have to change the buttons in your tab bar manually then you have not set them up properly. The system takes care of that for you. If you have properly setup an edit button then you don't even manually have to call setEditing:animated: actually.
I think you should review some UITableView sample code.