Issue with self.navigationController and pushViewController - objective-c

I am having trouble pushing from a tableview to a detail view. When I click the tableview cell, the cell highlights but does not push to the detail view. I am using this to transition to the detail view:
[self.navigationController pushViewController:detailViewController animated:YES];
I have read that this is a common issue, but am somehow unable to figure out a solution. My full .m file is below. If anyone has any recommendations that would be amazing. Thank you!
#import "ViewController.h"
#import "DetailViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"title";
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://website.com/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
news = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[mainTableView reloadData];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [news count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
}
cell.textLabel.text = textForMyLabel;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
detailViewController.title = [[news objectAtIndex:indexPath.row] objectForKey:#"name"];
detailViewController.newsArticle = [news objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
}

you try:
[self presentModalViewController: detailViewController animated:YES];

You can perform push oly with a UINavigationController, the above code will work if your Controller is UINavigationController. Since your trying to integrate two projects just check whether the RootViewController is a UINavigationController.

Related

objective-c send url according to my menu select

i have a custom UItableView . i am loading data from a API and my main view are
i am loading data from a API .
My problem is,i have a left-side menu, i want to send a url when user select any menu acoording to select menu view will load.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
if(indexPath.row ==0){
appdataModel.newsApiUrl = homePagesUrl;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}else if (indexPath.row ==1){
appdataModel.newsApiUrl = jatioNews;
NSLog(#"here 1 :%#",appdataModel.newsApiUrl);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}
else if (indexPath.row ==2){
appdataModel.newsApiUrl = jatioNews;
NSLog(#"here 1 :%#",appdataModel.newsApiUrl);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
[self.navigationController pushViewController:contView animated:YES];
}
}
#define homePagesNews #"http://198.72.115.125/~pratidin/api/topnews"
#define jatioNews #"http://198.72.115.125/~pratidin/api/categorynews/4"
here my api link . if user select Home-menu then view will load form homePagesNews API else user select second menu then view will from jatioNews API
from this code i am getting data
-(void)GetHomePageData{
NSString *urlString = [NSString stringWithFormat:#"%#",url];
NSURL *url = [[NSURL alloc]initWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSData *GETReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
res = [NSJSONSerialization JSONObjectWithData:GETReply options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers error:nil];
}
now i want when user select menu may home-menu or second-menu or third-menu according to user select url link will change and view will load in my ContactsTableViewController
my ContactsTableViewController viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
appdataModel = [AppDataModel getInstance];
appdataModel.newsApiUrl = homePagesUrl;
/**** for left side menu ***/
SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
[self.sideBarButton setTarget: self.revealViewController];
[self.sideBarButton setAction: #selector( revealToggle: )];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
/**** for Contractview***/
self.view.backgroundColor = [UIColor whiteColor];
NSString *path = [[NSBundle mainBundle] pathForResource:#"contacts" ofType:#"plist"];
contactsArray = [NSArray arrayWithContentsOfFile :path];
[self GetHomePageData];
[self.newsDataTableView reloadData];
}
some can tell me how can i solve my problem ... Thanks
Add a url property to ContactsTableViewController:
#interface ContactsTableViewController : UIViewController
#property NSURL *url;
...
#end
and in its viewDidLoad method you can load the data using whatever method you are using:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:self.url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Whatever
}];
Then set the URL from the tableview delegate method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
if (indexPath.row ==0){
appdataModel.newsApiUrl = homePagesUrl;
} else {
appdataModel.newsApiUrl = jatioNews;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self.revealViewController revealToggleAnimated:YES];
ContactsTableViewController *vc = [[ContactsTableViewController alloc] initWithNibName:#"ContactsTableViewController" bundle:nil];
vc.url = [NSURL URLWithString:appdataModel.newsApiUrl];
[self.navigationController pushViewController:vc animated:YES];
}

pdf is not shown in detailview on selecting a row in UITableView

I have a UITableView which as some rows. On selecting a row respective pdf should be displayed in detailview.detialview has UIWebView declared in it. I want to use for loop to directing to detailview. Below is sample code:
- (void)viewDidLoad
{
[super viewDidLoad];
arrCategorieslist=[[NSMutableArray alloc]initWithObjects:#"Total requests",#"Initiated",#"In process",#"Completed",#"Rejected",nil];
NSURL *url1=[NSURL URLWithString:#"http://www.........pdf"];
NSURL *url2=[NSURL URLWithString:#"http://www.........pdf"];
NSURL *url3=[NSURL URLWithString:#"http://www.........pdf"];
NSURL *url4=[NSURL URLWithString:#"http://www.........pdf"];
NSURL *url5=[NSURL URLWithString:#"http://www.........pdf"];
arrUrl=[[NSMutableArray alloc]initWithObjects:url1,url2,url3,url4,url5,nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [arrCategorieslist count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
}
cell.textLabel.text = [arrCategorieslist objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
PdfViewController *displayPdf=[[PdfViewController alloc]init];
displayPdf.title=[arrCategorieslist objectAtIndex:indexPath.row];
dispatch_async(dispatch_get_main_queue(), ^{
int i;
for (i=0;i<[arrUrl count];i++) {
NSURLRequest *request=[NSURLRequest requestWithURL:[arrUrl objectAtIndex:indexPath.row]];
NSLog(#"%#",[arrUrl objectAtIndex:i]);
[displayPdf.webView loadRequest:request];
}
});
[self.navigationController pushViewController:displayPdf animated:YES];
}
PdfViewController.m……..
- (void)viewDidLoad
{
[super viewDidLoad];
webView=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320,480)];
webView.autoresizingMask=(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin);
webView.scalesPageToFit=YES;
webView.delegate=self;
[self.view addSubview:webView];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
webView.delegate = self; // setup the delegate as the web view is shown
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[webView stopLoading]; // in case the web view is still loading its content
webView.delegate = nil; // disconnect the delegate as the webview is hidden
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// load error, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// report the error inside the webview
NSString* errorString = [NSString stringWithFormat:
#"<html><center><font size=+5 color='red'>An error occurred:<br>%#</font><center></html>",
error.localizedDescription];
[self.webView loadHTMLString:errorString baseURL:nil];
}
Modify your tableviewDelegate Function as follow
PdfViewController *displayPdf;//declared outside as if project is ARC then it is crashing
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
displayPdf=[[PdfViewController alloc]init];
displayPdf.title=[arrCategorieslist objectAtIndex:indexPath.row];
[self.navigationController pushViewController:displayPdf animated:YES];
NSURLRequest *request=[NSURLRequest requestWithURL:[arrUrl objectAtIndex:indexPath.row]];
[displayPdf.webView loadRequest:request];
}
dispatch_async(dispatch_get_main_queue(), ^{ }); This block is executing many times so I have removed it and replaced the code as above. I hope it will work for you

ViewController load methods called when view disappears?

I've got the following code in a viewController. I've got a NavigationController on the view (which is the child view - the code for the parent is working fine)
What happens is when I select an option on the parent, this viewController loads. The user can select an option from the child viewController to open a PDF file with a DocumentInteractionController (which works fine).
The problem is when I try going back to the parent viewController, messages are being sent to the child viewController as if it's still allocated. I saw something similar when I set it up since there were multiple calls to the methods in the child viewController.
Any thoughts on what I'm doing wrong?
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#synthesize node;
#synthesize replies;
#synthesize docController;
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
[self.tableView setContentOffset:CGPointZero animated:NO];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.docController init];
// Do any additional setup after loading the view from its nib.
}
- (void) dealloc
{
[self.docController release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.replies == nil)
{
self.replies = [[NSArray alloc] init];
self.actions = [[NSArray alloc] init];
}
if(self.replies.count == 0)
{
self.replies = [self.node nodesForXPath:#"./question/reply/text" error:nil];
self.actions = [self.node nodesForXPath:#"./question/reply/response/action" error:nil];
}
return self.replies.count;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"QuestionCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Get the object to display and set the value in the cell
NSString *cellText = [[replies objectAtIndex:indexPath.row] stringValue];
cell.textLabel.text = cellText;
return cell;
}
- (void) showOptionsMenu:(NSString *) fileName
{
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:fileName ofType:#"pdf"];
NSURL *fileURL = [NSURL fileURLWithPath:fileToOpen];
self.docController = [self setupControllerWithURL:fileURL usingDelegate:self];
bool didShow = [self.docController presentOptionsMenuFromRect:CGRectMake(0, 0, 150, 150) inView: self.view animated:YES];
if(!didShow)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"" message:#"Sorry, app not found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *action = [[self.actions objectAtIndex:indexPath.row] stringValue];
[self showOptionsMenu:action];
}
- (UIDocumentInteractionController *) setupControllerWithURL: (NSURL *) fileURL usingDelegate:(id <UIDocumentInteractionControllerDelegate>) interactionDelegate
{
UIDocumentInteractionController *interactionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
interactionController.delegate = interactionDelegate;
return interactionController;
}
#end
EDIT
Adding the code for the parent view controller...maybe there's something I'm doing wrong in there? I'm using GDataXML to load a Q&A app based on the contents of an XML file...
#implementation ViewController
#synthesize currentReply;
#synthesize questions;
- (void)viewDidLoad
{
[super viewDidLoad];
[self setUpQuestions];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[super dealloc];
}
- (void) setUpQuestions
{
// create and init NSXMLParser object
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"query" ofType:#"xml"];
NSData *xml_data = [[NSData alloc] initWithContentsOfFile:filePath];
NSError *error;
GDataXMLDocument *xmlDoc = [[GDataXMLDocument alloc] initWithData:xml_data options:0 error:&error];
NSArray *rootDataArray = [xmlDoc.rootElement nodesForXPath:#"//query" error:nil];
for (GDataXMLElement *rootDataElement in rootDataArray)
{
// Allocate the query object
self->query = [[[Query alloc] init] autorelease];
// Name
NSArray *query_title = [rootDataElement elementsForName:#"text"];
if (query_title.count > 0)
{
GDataXMLElement *queryTitle = (GDataXMLElement *) [query_title objectAtIndex:0];
self->query.queryTitle = [[[NSString alloc] initWithString:queryTitle.stringValue] autorelease];
}
NSArray *query_first_question = [rootDataElement elementsForName:#"question"];
NSArray *replies = [NSArray alloc];
questions = [[NSMutableArray alloc] init];
if(query_first_question.count == 1)
{
GDataXMLElement *fq = (GDataXMLElement *) [query_first_question objectAtIndex:0];
replies = [fq elementsForName:#"reply"];
for (GDataXMLElement *replyElement in replies)
{
[questions addObject:replyElement];
}
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Only one section.
return 1;
}
- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
switch(section)
{
case 0:
return questions.count;
break;
case 1:
return 1;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"QuestionCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
// Get the object to display and set the value in the cell.
GDataXMLElement *questionAtIndex = questions[indexPath.row];
NSString *cellText = [[[questionAtIndex elementsForName:#"text"] objectAtIndex:0] stringValue];
cell.textLabel.text = cellText;
//cell.textLabel.text = [[questionAtIndex elementsForName:#"text"] objectAtIndex:0];
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSMutableString *msg = [NSMutableString new];
//[msg appendString:#"You selected row: "];
//[msg appendString:[NSString stringWithFormat:#"%i",indexPath.row]];
//UIAlertView *alertMsg = [[UIAlertView alloc] initWithTitle:#"Row Selected" message:msg delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
//[alertMsg show];
if (questions != nil)
{
GDataXMLElement *selectedReply = (GDataXMLElement *) [questions objectAtIndex:indexPath.row];
DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
dvc.node = selectedReply;
[self.navigationController pushViewController:dvc animated:YES];
[dvc release];
}
}
EDIT
I've tried profiling and looking for zombies, but when the crash occurs there are no zombie objects flagged. It throws the following error in the console:
[UIView _forgetDependentConstraint:]: message sent to deallocated instance 0x1e8ab810
I have seen this Issue before also !!!
Answer : Turn Off "AutoLayout".
I am guessing the error occurred due to new feature in ios called AutoLayout. It looks like Compiler has created some NSLayoutConstraint objects and due to some reason the objects were released more than they should. Deletion and Re-Creation, forces Xcode to Re-Build the Constraints. But,I am not 100% sure.
Try to Un-Check "AutoLayout", if it can solve your Problem.
Your DetailViewController code is fine - not actually fine, as you're leaking self.replies and self.actions, and the [self.docController init] is very odd and probably wrong (always alloc and init together) - but the lifecycle code on this end looks fine. The problem is almost certainly in the parent view controller (or possibly the document controller if you're creating a retain cycle there). If the parent view controller is holding onto a pointer to the detail view controller, it won't actually be deallocated and accessing the view or any property thereof will cause -viewDidLoad to be called again.
From what I understood, your parent view controller is setting the node here:
dvc.node = selectedReply;
and it's never being released from your DetailViewController.
I'm assuming that your GDataXMLElement in the DetailViewController header is set as "retain".
And there's some leaking problems as icodestuff pointed out.

Call Multiple ViewController with UIViewController

In my project I have tableView with 10 cells. And in didSelectRowAtIndexPath all cells have multiple ViewController (files) so, my didSelectRowAtIndexPath looks like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0) {
CallViewController *viewc = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
[self.navigationController pushViewController:viewc animated:YES];
}else if(indexPath.row == 1) {
BirthdayViewController *viewc = [[BirthdayViewController alloc] initWithNibName:#"BirthdayViewController" bundle:nil];
[self.navigationController pushViewController:viewc animated:YES];
}
so I don't want these conditions
I want my code be clean
I would suggest you to have an array that contains the Class object of your class and then create object and push like
//view did load
mutableArr = [[NSMutableArray alloc] init];
[mutableArr addObject:[CallViewController class]];
[mutableArr addObject:[BirthdayViewController class]];
....
....
Then in your
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < [mutableArr count]) {
Class *obj = [mutableArr objectAtIndex:indexPath.row];
UIViewController *controller = [[objc alloc] initWithNibName:NSStringFromClass(obj) bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
}
OR if this is looking more weird then you can do like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *controller = nil;
switch(indexPath.row) {
case 0:
controller = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
break;
case 1;
controller = [[BirthdayViewController alloc] initWithNibName:#"BirthdayViewController " bundle:nil];
break;
}
[self.navigationController pushViewController:controller animated:YES];
}
What is your underlying data model for tableview? If you could add additional attribute as ViewController Class Name you could do something like
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *row = [rowData objectAtIndex:indexPath.row];
Class viewControllerClass =
NSClassFromString([row objectForKey:#"viewControllerClassName"]);
//Default VC init looks for nib file named as VC afaik, if not, you could
//add another attribute with init selector name
UIViewController *viewController =
[[viewControllerClass alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
You can create array of strings corresponding to file names and use NSClassFromString function to allocate view controllers
NSArray *viewControllers = [NSArray arrayWithObjects:#"VC1", #"VC2", #"VC3", nil];
id viewController = [[NSClassFromString([viewControllers objectAtIndex:indexPath.row]) alloc] initWithNibName:[viewControllers objectAtIndex:indexPath.row] bundle:nil];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];
You can do this:
Add all your classes to NSArray, and select the correct class by the indexPath.row.
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray * conrollersClasses =#[[CallViewController class],[BirthdayViewController class]];
UIViewController *controller = [[conrollersClasses[indexPath.row] alloc] init];
[[self navigationController] controller animated:YES];
}

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]}];