Assertion failure in -[UITableView _endCellAnimationsWithContext:] when "New" button pressed - objective-c

My app compiles fine, but when I hit the "New" button in the header file, it crashes, returning this crash message:
2012-04-30 11:44:40.599 Homepwner[13233:f803] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1021
2012-04-30 11:44:40.601 Homepwner[13233:f803] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (1), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).'
*** First throw call stack:
(0x13cd022 0x155ecd6 0x1375a48 0x9ae2cb 0x9c103 0xa76d2 0xa7711 0x39ff 0x13cee99 0x1a14e 0x1a0e6 0xc0ade 0xc0fa7 0xc0266 0x3f3c0 0x3f5e6 0x25dc4 0x19634 0x12b7ef5 0x13a1195 0x1305ff2 0x13048da 0x1303d84 0x1303c9b 0x12b67d8 0x12b688a 0x17626 0x294d 0x28b5)
terminate called throwing an exception(lldb)
Have been looking thru my ItemsViewController.m but can't figure out what is wrong, since I have not changed any of the UITableView methods.
Can you tell me what's wrong? Thanks in advance.
ItemsViewController.m
#import "ItemsViewController.h"
#import "BNRItemStore.h"
#import "BNRItem.h"
#implementation ItemsViewController // Incomplete implementation
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController = [[DetailViewController alloc]init];
NSArray *items = [[BNRItemStore sharedStore]allItems];
BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];
//Give detail view controller a pointer to the item object in a row
[detailViewController setItem:selectedItem];
// Push it onto the top of the navigation controller's stack
[[self navigationController]pushViewController:detailViewController animated:YES];
}
-(id)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
UINavigationItem *n = [self navigationItem];
[n setTitle:#"Homepwner"];
}
return self;
}
-(id)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[BNRItemStore sharedStore]allItems]count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Check for a reusable cell first, use that if it exists
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
// If there is no reusable cell of this type, create a new one
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
// Set the text on the cell with the description of the item
// that is at the nth index of items, where n = row this cell
// will appear in on the tableview
BNRItem *p = [[[BNRItemStore sharedStore]allItems]objectAtIndex:[indexPath row]];
[[cell textLabel]setText:[p description]];
return cell;
}
-(UIView *)headerView
{
// If we haven't loaded the headerView yet
if (!headerView) {
//Load HeaderView.xib
[[NSBundle mainBundle]loadNibNamed:#"HeaderView" owner:self options:nil];
}
return headerView;
}
-(UIView *)tableView:(UITableView *)tv viewForHeaderInSection:(NSInteger)sec
{
return [self headerView];
}
-(CGFloat)tableView:(UITableView *)tv heightForHeaderInSection:(NSInteger)sec
{
// The height of the header view should be determined from the height of the
// view in the XIB file
return [[self headerView]bounds].size.height;
}
-(IBAction)toggleEditingMode:(id)sender
{
// If we are currently in editing mode
if ([self isEditing]) {
// Change text of button to inform user of state
[sender setTitle:#"Edit" forState:UIControlStateNormal];
// Turn off editing mode
[self setEditing:NO animated:YES];
} else {
// Change text of button to inform user of state
[sender setTitle:#"Done" forState:UIControlStateNormal];
// Enter editing mode
[self setEditing:YES animated:YES];
}
}
-(IBAction)addNewItem:(id)sender
{
// Create a new BNRItem and add it to the store
BNRItem *newItem = [[BNRItemStore sharedStore]createItem];
//Incompatible pointer types initializing 'BNRItem *__strong' with an expression of type 'NSArray*'
// Figure out where that item is in the array
int lastRow = [[[BNRItemStore sharedStore]allItems]indexOfObject:newItem];
NSIndexPath *ip = [NSIndexPath indexPathForRow:lastRow inSection:0];
// Insert this new row into the table
[[self tableView]insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationTop];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// If the table view is asking to commit a delete command...
if(editingStyle == UITableViewCellEditingStyleDelete)
{
BNRItemStore *ps = [BNRItemStore sharedStore];
NSArray *items = [ps allItems];
BNRItem *p = [items objectAtIndex:[indexPath row]];
[ps removeItem:p];
// We also remove that row from the table view with an animation
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath
{
[[BNRItemStore sharedStore]moveItemAtIndex:[sourceIndexPath row]
toIndex:[destinationIndexPath row]];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[self tableView] reloadData];
}
#end

Related

PFQueryTableViewController doesn't find my class

The login and signing up process work well in my code, therefore i have an existing User class, but i'm getting this error Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' setObjectForKey: object cannot be nil (key: classname)'
First throw call stack: when i launch the simulator. So i don't understand which class missing or nil, because i've set the User class to query on. (I wanna display the usernames in a list)
#interface Contacts ()
#end
#implementation Contacts
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"User";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"username";
// The title for this table in the Navigation Controller.
self.title = #"Title";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 5;
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
NSLog(#"Current user: %#", currentUser.username);
} else {
[self performSegueWithIdentifier:#"goLogin" sender:self];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - Parse
- (void)objectsDidLoad:(NSError *)error {
[super objectsDidLoad:error];
// This method is called every time objects are loaded from Parse via the PFQuery
}
- (void)objectsWillLoad {
[super objectsWillLoad];
// This method is called before a PFQuery is fired to get more objects
}
// Override to customize what kind of query to perform on the class. The default is to query for
// all objects ordered by createdAt descending.
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"priority"];
return query;
}
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"contactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell
cell.textLabel.text = [object objectForKey:#"text"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Priority: %#", [object objectForKey:#"priority"]];
return cell;
}
/*
// Override if you need to change the ordering of objects in the table.
- (PFObject *)objectAtIndex:(NSIndexPath *)indexPath {
return [objects objectAtIndex:indexPath.row];
}
*/
/*
// Override to customize the look of the cell that allows the user to load the next page of objects.
// The default implementation is a UITableViewCellStyleDefault cell with simple labels.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"NextPage";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = #"Load more...";
return cell;
}
*/
#pragma mark - Table view data source
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqual:#"goLogin"]) {
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
}
- (IBAction)logoutButton:(id)sender {
[PFUser logOut];
[self performSegueWithIdentifier:#"goLogin" sender:self]; }
#end
Are you sure the initWithStyle method is called? If you're using storyboards, you need to use initWithCoder instead of initWithStyle.
Update
Also, replace
// The className to query on
self.parseClassName = #"User";
with
// The className to query on
self.parseClassName = #"_User";

How to solve IOS exception after creating tableview?

After creating a second tableviewcontroller i got the following exception when clicking on the tabbarItem that was connected tot this tableView:
2012-09-18 10:45:33.202 testStoryboard[5792:14203] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Requesting the window of a view (<UITableViewCell: 0x6b80190; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; alpha = 0; opaque = NO; autoresize = W; layer = (null)>) with a nil layer. This view probably hasn't received initWithFrame: or initWithCoder:.'
*** First throw call stack:
(0x14b2022 0xeb2cd6 0x145aa48 0x145a9b9 0x4b7c4 0x4d612 0x5246f 0x4c01b 0x6c494 0x9c838 0xb00e6 0xb03ce 0x9bcbd 0xaa6f1 0x53d21 0x14b3e42 0x1d83679 0x1d8d579 0x1d124f7 0x1d143f6 0x1da1160 0x25f30 0x148699e 0x141d640 0x13e94c6 0x13e8d84 0x13e8c9b 0x139b7d8 0x139b88a 0x15626 0x20fd 0x2065)
terminate called throwing an exception(lldb)
Edit: here's my code:
// SecondTableViewController.m
#import "SecondTableViewController.h"
#interface SecondTableViewController ()
#end
#implementation SecondTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Initialize the array.
myArray2 = [[NSMutableArray alloc] init];
//Add items
[myArray2 addObject:#"Iceland"];
[myArray2 addObject:#"Greenland"];
[myArray2 addObject:#"Switzerland"];
[myArray2 addObject:#"Norway"];
[myArray2 addObject:#"New Zealand"];
[myArray2 addObject:#"Greece"];
[myArray2 addObject:#"Rome"];
[myArray2 addObject:#"Ireland"];
//Set the title
self.navigationItem.title = #"Countries";
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#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 [myArray2 count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [UITableViewCell alloc];
}
cell.textLabel.text = [myArray2 objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
I'm verry new to IOS, can someone set me in the right direction?
Your initiation of the cell is not complete, you have to init the cell, not just alloc it.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

My second level detail controller is not showing the initWithObjects in my array in the viewDidLoad method

I am creating a Two Level table view. And the second view is supposed to have the list of the movies I have listed below in my viewDidLoad method, but it is not showing.(You can see my screen shots attached)Does anyone know which file where I can look to see why it is not showing? The code below is from my DisclosureButtonController.m file which is to display this information after I hit the Disclosure Buttons instance on the First Level screen.
Regards,
#import "LWWDisclosureButtonController.h"
#import "LWWAppDelegate.h"
#import "LWWDisclosureDetailController.h"
#interface LWWDisclosureButtonController ()
#property (strong, nonatomic) LWWDisclosureDetailController *childController;
#end
#implementation LWWDisclosureButtonController
#synthesize list;
#synthesize childController;
//- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
//{
// self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//if (self) {
// Custom initialization
//}
//return self;
//}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = [[NSArray alloc] initWithObjects:#"Toy Story", #"A Bug's Life", #"Toy Story 2", #"Monsters, Inc.", #"Finding Nemo", #"The Incredibles", #"Cars", #"Ratatouille", #"WALL-E", #"Up", #"Toy Story 3", #"Cars 2", #"Brave", nil];
self.list = array;
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.list = nil;
self.childController = nil;
// Release any retained subviews of the main view.
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString * DisclosureButtonCellIdentifier = #"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DisclosureButtonCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier];
}
NSUInteger row = [indexPath row];
NSString *rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hey, boss do you see the disclosure button?" message:#"If you're trying to drill down, touch that instead mate!" delegate:nil cancelButtonTitle:#"Won't happen again" otherButtonTitles:nil];
[alert show];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *)indexPath
{
if (childController == nil)
{
childController = [[LWWDisclosureDetailController alloc]initWithNibName:#"LWWDisclosureDetail" bundle:nil];
}
childController.title = #"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSString *selectedMovie = [list objectAtIndex:row];
NSString *detailMessage = [[NSString alloc]initWithFormat:#"You pressed the disclosure button for %#.", selectedMovie];
childController.message = detailMessage;
childController.title = selectedMovie;
[self.navigationController pushViewController:childController animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Why not start the array with the VC instead of after the VC loads? Try overriding the init method.
- (id) init {
if((self == [super init])) {
//load your array here and set
}
return self;
}
That way, on older devices, you don't have to wait after the view loads to see the array. But, however, this is my preference. I love to override init methods and create my own.
Also, for some weird reason on my SDK, I have to use NSMutableArray instead of NSArray or it won't work. Maybe you have the same issue?
Also, I've noticed NSString *selectedMovie. Instead of using just "row", use the getter indexPath.row.
Hope these suggestions helped!
Call:
[self.tableView reloadData]; (put in place of self.tableView the var or property connected to the tableView)
after the:
self.list = array;
code line in the viewDidLoad method
and put a
NSLog(#"number of rows: %d", [self.list count]);
in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
to check if it is not zero.

Repeated issues in ItemsViewController.m

Am getting repeated issues in ItemsViewController.m even though I have not changed anything in the relevant methods. Before there were some issues which I asked about on SO earlier, then corrected them, but they have popped up again. Have not made any changes to the methods/areas which are kicking up a fuss again. Have commented out the problem areas.
Could there be compiler issues?
Here is the file; thanks in advance.
ItemsViewController.m
#import "ItemsViewController.h"
#import "BNRItemStore.h"
#import "BNRItem.h"
#implementation ItemsViewController //#end is missing in implementation context
- (id)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
UINavigationItem *n = [self navigationItem];
[n setTitle:#"Homepwner"];
// Create a new bar button item that will send
// addNewItem: to ItemsViewController
UIBarButtonItem *bbi = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addNewItem:)];
// Set this bar button item as the right item in the navigationItem
[[self navigationItem] setRightBarButtonItem:bbi];
[[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
}
return self;
}
- (IBAction)addNewItem:(id)sender
{
// Create a new BNRItem and add it to the store
BNRItem *newItem = [[BNRItemStore defaultStore] createItem];
DetailViewController *detailViewController = [[DetailViewController alloc]initForNewItem:YES];
[detailViewController setItem:newItem];
[detailViewController setDismissBlock:^{[[self tableView]reloadData];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:detailViewController];
[navController setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:navController animated:YES completion:nil];
}
- (id)initWithStyle:(UITableViewStyle)style //use of undeclared identifier 'initWithStyle'
{
return [self init];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[self tableView] reloadData];
}
- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath
{
[[BNRItemStore defaultStore] moveItemAtIndex:[fromIndexPath row]
toIndex:[toIndexPath row]];
}
- (void)tableView:(UITableView *)aTableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:NO];
NSArray *items = [[BNRItemStore defaultStore] allItems];
BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];
// Give detail view controller a pointer to the item object in row
[detailViewController setItem:selectedItem];
// Push it onto the top of the navigation controller's stack
[[self navigationController] pushViewController:detailViewController
animated:YES];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
if ([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad) {
return YES;
} else {
return (io==UIInterfaceOrientationPortrait);
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// If the table view is asking to commit a delete command...
if (editingStyle == UITableViewCellEditingStyleDelete)
{
BNRItemStore *ps = [BNRItemStore defaultStore];
NSArray *items = [ps allItems];
BNRItem *p = [items objectAtIndex:[indexPath row]];
[ps removeItem:p];
// We also remove that row from the table view with an animation
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [[[BNRItemStore defaultStore] allItems] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of UITableViewCell, with default appearance
// Check for a reusable cell first, use that if it exists
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
// If there is no reusable cell of this type, create a new one
if (!cell) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"UITableViewCell"];
}
// Set the text on the cell with the description of the item
// that is at the nth index of items, where n = row this cell
// will appear in on the tableview
BNRItem *p = [[[BNRItemStore defaultStore] allItems]
objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[p description]];
return cell;
}
#end // expected '}'
This line looks to be missing the end the of the block:
[detailViewController setDismissBlock:^{[[self tableView]reloadData];
should be:
[detailViewController setDismissBlock:^{[[self tableView]reloadData]}];

cellForRowAtIndexPath returns null but really need similar method

I have a UITableView in my UITableViewController (lol, obviously) but I need to get a cell at a given index inside the - (void)viewWillAppear:(BOOL)animated method.
Now, my cells are static and I create them in the interface builder. If I call
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:previously_selected_cell.integerValue inSection:0]];
it returns null for the cell. I only have 3 static cells in 1 sections. I tried both sections 0 and 1 and both return null.
Currently I have removed the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method because if I add it, it will clear the UITableView of all my static cells.
Is there a method I can call in - (void)viewWillAppear:(BOOL)animated that will return a cell at a given index?
Thanks in advance!
EDIT: I checked out this stackoverflow question but I'm using static cells without cellForRowAtIndexPath so that question didn't help. :(
EDIT2: I'm trying to set the accessory type of the cell when the view loads. But only on a certain cell, that cell being the one the user selected before he quit the app.
#import "AutoSyncSettings.h"
#import "CDFetchController.h"
#implementation AutoSyncSettings
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSArray *objects = [results fetchedObjects];
NSNumber *sync_setting;
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
sync_setting = [object valueForKey:#"wifi_setting"];
NSLog(#"(Settings)sync_setting: %#",sync_setting);
NSLog(#"(Settings)sync_setting int value: %i",sync_setting.integerValue);
NSLog(#"(Settings)TableView: %#",self.tableView);
//cell is null, even after this.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:wifi_settings.integerValue inSection:0]];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//cell is still null. WHY OH WHY? :(
objects = nil;
}
cdfc = nil;
results = nil;
objects = nil;
sync_setting = nil;
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
for (int i = 0; i < [tableView numberOfRowsInSection:indexPath.section]; i++)
{
if([[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]] accessoryType] == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]].accessoryType = UITableViewCellAccessoryNone;
}
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSManagedObjectContext *context = [results managedObjectContext];
NSArray *objects = [results fetchedObjects];
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
else
{
//INSERT NEW OBJECT
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"SETTINGS" inManagedObjectContext:context];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
}
#end
I have a project doing exactly this and it works perfectly. However, it doesn't work unless you call [super viewWillAppear:animated] before trying to access the cells in this manner.
The base implementation presumably loads in the cells from the storyboard.
I want to add a checkmark accessory to the previously selected cell,
the previously_selected_cell variable gets stored even if the app
quits/crashes
The way to go will be to control the indexPath in your cellForRowAtIndexPath implementation and act if it's equal to previously_selected_cell.integerValue:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// usual cache lookup, allocation of the cell, etc
if (indexPath.row == previously_selected_cell.integerValue) {
// add checkbox here
} else {
// remove checkbox
}
}