tableview reloaddata in masterview from detail view - objective-c

I have a master-detail application that has a tableview in the masterViewController and in the detailview you can edit and add info into textfields and so on. I have a save button as the rightBarButtonItem in the detail view. If they did not save their work and they hit back I have a UIAlertView that popsup asking them if they want to save their work. Behind the alertview the detailview is still dismissed and the masterviewcontroller is now showing.
So when I hit save the tableview does not update. I have [tableview reloadData] in my masterviewcontroller viewWillAppear but it does not work because the viewappears behind the alertview before the user can hit save. I would like to call the [tableview reloadData] (or something similar) in this method here which is called from my detailview.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
I can't just call [tableview reloadData] because the alertViews delegate is set as the detailview because it is pulling all the information from the textfields to save into the plist if they push save on the alertview. Is there a way I can call [tableView reloadData] from my alertView?

If I understand your problem correctly, you are dismissing the detailView before any button is tapped on the alertView. I don't know where you save your data and where the tableView retrieves it from but try waiting for user interaction on the alertView.
In the code where you pop the alertView to ask for save, do nothing else.
- (void)yourBackButtonAction //i assumed this is your method when they hit 'back'
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:#"Would you like to save your work?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alertView show];
[alertView release];
}
And in the delegate method, save the data and dismiss the detailView:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) //yes
{
//save your data
[self.navigationController dismissModalViewControllerAnimated:YES];
}
else // no
[self.navigationController dismissModalViewControllerAnimated:YES];
}
Now in your masterViewController's viewWillAppear method, [self.tableView reloadData] should work.

I figured it out. What I did was created a property of UITableViewController in my DetailViewController.h file and named it masterView then synthesized it in its .m file. I then went into my masterViewController.m file and found the method tableView:didSelectRowAtIndexPath:and set my detailsViewController.masterView property to self (self being the masterViewController).
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.detailViewController.masterView = self;
}
I then went into my UIAlertView Save Method and called reloadData on the masterViews tableView
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
[masterView.tableView reloadData];
}
}
This is very much like passing info to an array or dictionary in the detail view from the tableView indexPath.row like this below (which is also in the method tableView:didSelectRowAtIndexPath:)
self.detailViewController.detailItem = object;

set the property of the tableview and try
[self.tableView reloadData]

I guess you have to create a delegate method for this.
Create a protocol,
Create one method inside for e.g. - (void) updateMyMasterTable;
Create a delegate instance like id <ProtocolName> obj; in your detail class & write in .h file.
Synthesize it.
When you want to reload your master's tableview call [obj updateMyMasterTable];
In your master class .m file implement - (void) updateMyMasterTable method & call [tableView reloadData];

Related

Can not get correct value of indexPath.row in prepareForSegue when UILabel or UIImageView in a cell is tapped,

I am developing iOS App with UITableView.
When UILabel or UIImageView in a cell is tapped, segue is called and move to another screen.
I am writing down the following code, however I can not get correct value of indexPath.row in prepareForSegue.The value is always 0.
- (void)goToDetail: (UITapGestureRecognizer *)sender{
[self performSegueWithIdentifier:#"showDetail" sender:self];
NSLog(#"aaa");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.article = _article[indexPath.row];
NSLog(#"bbb%d",indexPath.row);
}
}
NSLog says following.
2014-08-08 17:50:23.267 eleventhtest[27374:60b] bbb0
2014-08-08 17:50:23.269 eleventhtest[27374:60b] aaa
Could you tell me how to solve this problem?
As just one of the possible options, you can set tag for label/imageView and gesture recognizer when you are creating cells. The tag would be the same as the indexPath.row.
In goToDetail method you can assign this tag to some internal property, and then use it in prepareForSegue.
If you're calling goToDetail in the didSelectRowAtIndexPath method AND have a segue wired from the prototype row to your detailViewController, then the segue fires BEFORE the goToDetail method.
Solution: segue directly from your view controller to your detailViewController and call [self performSegueWithIdentifier:#"showDetail" sender:self]; in the didSelectRowAtIndexPath method.
Also you can create a NSIndexPath property and set the value in the didSelectRowAtIndexPath method, the segue would then use that property instead of trying to access the [self.tableView indexPathForSelectedRow].

UIAlertView button to display viewController

I've been looking all over the internet for a solution to this problem, yet to find one that I can understand. So here it goes.
I have my iOS application, on which on the first launch of the application, will display a UIAlertView. I want one of the buttons to send the user to a new viewController to view some essential information.
I have gotten my UIAlertView configured properly, here's the code for the actionSheet:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
//Code to open a new viewController???
}
if (buttonIndex == 1)
{
//User can exit the application if they do not wish to continue
exit(0); }
}
}
I have a viewController created named webViewViewController, that's what I want users to reach when they tap the first button. Any ideas on how to do this? I have ARC disabled, other 'solutions' i've come across keep giving me errors.
Thanks all, would appreciate some guidance here.
If your current viewcontroller is in a Navigation Controller:
UIViewController *myViewController = [[UIViewController alloc] init];
myViewController.title = #"My First View";
//to push the UIView.
[self.navigationController pushViewController:myViewController animated:YES];
And never use exit(0)!
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
NewViewController *controller=[[NewViewController alloc]initWithNibName:#"NewViewController" bundle:nil];
self.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentViewController:controller animated:YES completion:nil];
}
drasick has given sufficient answer but if you need to use model view controller refer above.
Use:
UIViewController *yourViewController = [[UIViewController alloc] init];
[self.navigationController presentModalViewController:myViewController animated:YES];
to push a modalViewController.(This is depriciated in iOS 6, but will work)

Cannot dismiss the Search view

I have a parent class with tableview and searchbar over it which is a subclass of tableview controller. Delegates for the searchBar and searchdisplaycontroller are set in a seperate class inherited from UISearchdisplaycontroller. The datasource and delegates for tableview and searchbar are handled in this class seperately. The classes are under ARC.
Hence, When a user taps on search, the control transfers from FilesListController (parent)class to this class. Now, When a user taps on cancel button, the searchbar delegate set in this class i.e.
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar
is CALLED but DOESN'T serve the purpose of dismissing the full screen searchtableview and return to the parentviewcontroller. However, if I don't write this delegate in the search class, it works properly. I have set the searchbar delegates in xib and on calling:
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
like this:
self.searchResultsTableView.delegate = self;
self.searchResultsTableView.dataSource = self;
[parentFileViewController.searchDisplayController setDelegate:self];
Where am I going wrong? Thanks in advance.
If you want to dismiss a UISearchBar with a SearchBarController, just use this Code:
[self.searchDisplayController setActive:NO animated:YES];
you should implement resign the responder in the delegate function i.e
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
[searchBar resignFirstResponder];
}
Memory warnings can appear at any time during the application run time, you must assume a memory warning will happen and the view and disposable objects will have to be recreated.
We are handling such situation by setting to nil our arrays:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if([self isViewLoaded] && self.view.window == nil)
{
self.view = nil;
keys = nil;
names = nil;
errorDuringNetworkCall = nil;
}
}
And by dismissing the search bar tableview before performing the segue operation:
[self performSegueWithIdentifier:#"navigateToNextScreen" sender:self];
self.searchBar.text = #"";
[self.searchDisplayController setActive:NO animated:YES];
After a Memory warning is received the viewDidLoad method is called again and the arrays are populated, the search bar will continue to be useful.work without issues

reloadData doesn't call cellforrowatindexpath

Maybe it's a similar beginning, but it's true.
first of all sorry if this isn't formatted correctly, first time doing this. I've been using stackoverflow to find help for a long time now and it's been very helpful (thank you all), but this is the first time I've posted a question of my own. This question has been asked many times, but when I call [self.tableView reloadTable] the methods numberOfSectionsInTableView and numberOfRowsInSection are called but not cellForRowAtIndexPath.
Every answer I've seen when searching has been a variation of:
The tableView is nil
numberOfRowsInSection is 0
tableView's delegate/data source not set. None of these are the case for me so I'm wondering what else could be wrong.
But I'm not sure 4. calling reloadTable on the wrong uiTableView. Or it's about some other false.
Now my APP is similar to dropbox,
first when we log into it, we get a file list(include directories) in the TableView.also, I added a toolbar in the bottom of the view by [self.navigationController.view addSubview:toolBar], when I touch the button item "refresh", it calls [self.tableView reloadData] and works well.
Second when we select a directory we will get a new file list table which is pushViewController by self.navigationController, but this time when we touch the "refresh", the statement [self.tableView reloadData] calls numberOfSections, numberOfRows, not cellForRowAtIndexPath
Any ideas as to why cellForRow's not being called the Second time? Thanks in advance.
FileListViewController.h
#interface FileListViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
FileListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (isDir) {
FileListViewController *fileListViewController = [[FileListViewController alloc] init];
[self.navigationController pushViewController:fileListViewController animated:YES];
}
}
- (void)refresh
{
[Utilities refresh];//Utilities is my custom class.
[self viewDidLoad];
[self.tableView reloadData];
}
My return number of section and row in table view is not 0.
When I added NSLog(#"Calling reloadData on %#", self.tableView); into "refresh":
- (void)refresh
{
[Utilities refresh];//Utilities is my custom class.
[self viewDidLoad];
NSLog(#"Calling reloadData on %#", self.tableView);
[self.tableView reloadData];
}
Then it returns Calling reloadData on ; contentOffset: {0, 0}>. Delegate: FileListViewController, DataSource: FileListViewController
You should not manually call [self viewDidLoad]. This method is designed to be overridden, and is automatically called. For more information, please read this documentation.

Objective-C, Storyboard: instantiateViewControllerWithIdentifier returns nil

I have a UITableViewController with a storyboard push segue linking from the prototype cell to a detail page, a regular old UIViewController. In the storyboard, the detail ViewController has an identifier, and the segue has an identifier which is the same as the detail identifier except that the first letter is lowercase. Furthermore, the detail ViewController has a "custom class" (AttractionDetailViewController) selected in the class pulldown.
Doesn't work. The problem is that instantiateViewControllerWithIdentifier:#"AttractionDetails returns nil.
Relevant code. First the prepareForSegue method which the debugger has never entered.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"attractionDetails"])
{
AttractionDetailViewController *attrDetailVC = [segue destinationViewController];
}
}
Instead it goes into this method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//AttractionDetailViewController *attrDetailVC = [[AttractionDetailViewController alloc] init];
AttractionDetailViewController *attrDetailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"AttractionDetails"];
NSIndexPath *selIndexPath = [self.tableView indexPathForSelectedRow];
attrDetailVC.theAttraction = [attractions objectAtIndex:indexPath.row];
[self.navigationController pushViewController:attrDetailVC animated:YES];
}
Since instantiateViewControllerWithIdentifier returns nil it throws an exception of course. The really interesting thing is, if I use the alloc init line instead, it works, but the screen is all black.
Anyway, I've read up about this and tried a few different things and I'm still stymied. Does anyone have any suggestions?
The problem is that you didn't instantiate your master view controller (the UITableViewController) from the storyboard, so its storyboard property is nil.