How to reset view each time its closed? - iphone

I have a table view that displays contact information. I have another view that acts as a "contact pad." Basically it has either empty or text filled rows. I want it to have empty rows (or default state) when the user taps on a button on the tableview and I want it to pre-populate text when the user taps a row on the tableview. My methods for writing/reading to the datasource work fine, but once the "contact pad" view is brought up; it saves its state.
For example, if I open the "contact pad" view with the button then it shows the proper default state. Then if I open the "contact pad" view via tapping on a row it will display the correct text, but if I go try to open it again via the button then it will not re-show the default state and instead will show the text from before.
How do I reset a view once it has been closed? Do I call dealloc() before [self removeFromSuperview]?

In the viewWillAppear method, just do a
[self.tableView reloadData];
This method will be called every time there is a navigation or each time the view is opened.

Just remember that after you add your view as a subview its retain count goes up by 1.
So if you remove it from the superview it comes down by 1. You should release your subview after you add it to another view. This way when you call removeFromSuperview it counts get down by one and gets freed totally.

Related

Moving table view cells from one view controller to another

I am new to stack overflow and a student currently learning objective-C at university. I am building an APP for the science museum in London and I'm creating an events planner.
I have two table views set up in two different View Controllers.
The first View controller and table view is called "Events" and it holds all of the current days events. When you click on an event, it goes into a new View Controller, gives more information about the event and has a button to "Add To Events", which pops up an alert saying: "Are you sure you want to add this to your events?" with an add button and dismiss button accordingly.
The information in this table view is populated using three NSMutableArray's. (One for title, subtitle and image).
The second view controller has an empty table view inside it. I am trying to make it so whenever a user finds an event they like, they can click into it, see more info and if they want to add it to their own events page, they can. I have got the "Add" button of the alert responding using an NSLog message, so the code to implement the adding to events would go there.
My question is, if i click on the first event, and then choose to add it to my events, how do i send the information of that specific tableviewcell that i clicked to display in the second view controllers table view ?
I have looked all over the place for information regarding this and have taken an abundance of Lynda courses online about IOS and objective-C, but I haven't been able to figure it all out.
Can anybody help?
First of all you shouldn't use three NSMutableArray's to populate your cells. Create one NSMutableArray and populate it with NSDictionarys with a key for the title, the subtitle and the image. Or even better: create a custom model (subclass of NSObject) for your Events and populate the NSMutableArray with those.
Now just like your NSMutableArray is the data source for your first table view controller you need another NSMutableArray as the data source for the second table view controller. When a user now clicks on "Add To Events" all you have to do is add the Event (Model or Dictionary) to the NSMutableArray of the second table view controller and either call - (void)reloadData on your table view so that it reloads ALL data or use the "Inserting, Deleting, and Moving Rows and Sections" methods from the UITableView Class Reference. This would be the better approach because it does not reload data that does not need to be reloaded.

iPhone Storyboard, programmatically calling segues, navigation issues

So I have an iPhone app. It has a simple structure, all based on a UINavigationController.
I have a storyboard that has one view, a segue to another view, etc. Now this other view has a UITextView that I do not want to edit on this screen - if the user taps this, I want it instead to fly over to a second screen which basically has the same text view, but this one is full-screen, and the user will edit the text on that screen before returning to the previous screen.
So I capture the textViewShouldBeginEditing method. I previously, in the storyboard editor, manually created a push segue from the previous view controller to this new view controller, and named it so that I can call it by it's identity, which I do with:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
// This is called when the user clicks into the textView as if to edit it.
// Instead of editing it, go to this other view here:
[self performSegueWithIdentifier:#"editMemoSegue" sender:self];
// Return NO, as I don't actually want to edit the text on this screen:
return NO;
}
Seems reasonable. And it works. Sorta. It does in fact shoot me over to that other view. That other view's events fire up, I set it's text view to become first responder, I edit the text on that screen. Everyone's happy.
Until I want to use the back button to return to the previous view.
Then I quickly find out - my navigation stack is foobared. Most of the time, I have, for some reason, TWO instances of my new editing controller on the stack, so the first time I hit the back button I get the same stuff over again. Then, oddly, occasionally, it will work as intended, and I will see my previous controller with only one back click.
I started reading the log, and I found this:
2012-12-09 09:41:03.463 APP[8368:c07] nested push animation can result in corrupted navigation bar
2012-12-09 09:41:03.818 APP[8368:c07] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2012-12-09 09:41:03.819 APP[8368:c07] Unbalanced calls to begin/end appearance transitions for <SecondController: 0x83881d0>.
So obviously, I'm doing something incorrectly here. The question is, what? And how do I do what I want in the way that correctly appeases the tiki gods of the iPhone framework?
Check to see if the textViewShouldBeginEditing is being called twice. I've noticed that these kinds of delegate calls sometimes are.
How is your #"editMemoSegue" being created on the storyboard? is it created from the textView? if it is then you should recreate it directly from the view controller or from the top status bar on the view controller that way it wont be called twice when you touch the trigger object and when you call it programmatically.

Where should I "save" changes in my iPhone view to 'create new' of an object?

I have a view that creates a new core data managed object, and fills in all the required properties and also allows optional ones. I originally had a "Done" button on the top left, and when that was pressed, I validated the object then saved and removed the view.
Now I have an edit/done type setup on the top right, so sometimes there are two identical "Done" buttons on the top of the view. I want to switch the left side button so that it just has the normal "Back" button, then somehow validate and stop the view from being removed if it doesn't validate. I can't find any way to capture the method called by that back button and modify it, and viewWillDisappear doesn't work cause there's no way to abort the disappearing.
How can I make this work? I need to validate this, then save, then remove the view if validate and save worked only.
It sounds like your view is a perfect candidate to be pushed modally instead of through the navigation controller stack.
Push the view that creates your NSManagedObject modally:
[self presentModalViewController:yourViewController animated:YES]
Then continue to use your top right EDIT/DONE button for editing/validation as you currently are and when validation is successful simply save your object and dismiss the modal view controller from the parent view controller:
[[self parentViewController] dismissModalViewControllerAnimated:YES];
For more details check http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW14
If you still want to use a button on the left hand side perhaps you can change the right button to say EDIT/CANCEL and add a DONE button on the left side that is only visible when you're not in EDIT mode. If appropriate you can point the DONE button to run through the same validation process before dismissing the modal view using the code above but it probably makes sense that the EDIT/CANCEL button takes care of it.
I hope this helps.
Rog
There is no documented way to intercept the standard back button of UINavigationController. If you want this functionality, your only option would be to customize leftBarButtonItem with a custom button.
When the user taps that button, you can first validate your object and then call popViewControllerAnimated:.
It's hard to mimic the look of the built-in back button, though.

Information from pushed viewController to rootViewController

Sort of a simple question. I have a tableview in a navigationcontroller. When I touch a cell, it pushes a view controller with the information from the cell, so I can edit it in the new view. Now thats working correct (we can call it the informationpath: "rootviewcontroller -> pushed viewcontroller"). But when I click save in the new view, I want the edited values to travel back to the rootviewcontroller before I call popviewcontroller (informationpath: "pushed viewcontroller -> rootviewcontroller"), so the edited values can be displayed in the tableview.
Whats the correct approach to this?
EDIT:
pushViewController and popViewController is working. I only asked for the best approach to get the edited information back to the rootViewController for display in the tableview, when Save-button (popViewController) was called. I guess I'll just have to edit the pList with the new information directly from the pushed viewController. Though I would prefer sending the new information to the rootViewController and have it handle the access to the pList-file.
I have the same situation - two tableviews. The first TV displays a list of database records and when one is tapped it goes through to the second TableView which displays the details of the record. I do this by pushing the details TableViewController onto the navigation controllers stack. So far so go and quite simple.
The problem I encountered was that after updating the record in the details table view (controller), I wanted to let the list table view controller know, so that it could update the list of records.
The first thing I did was to add a property to the details table view controller so that when a row was selected on the list of records, the list controller could pass the core data managed entity to the details controller.
At the same time, I also added the list controller as a observer of core data change events like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(dataSaved:) name:NSManagedObjectContextDidSaveNotification object:nil];
So if the details table view and controller update the record, the list controller has it's dataSaved: method called, passing a NSNotification object.
In the dataSaved: method I examine the object and if the core data entity being edited is in the updated list, then I set a flag to signal an update is required. However if there is a record in the inserted list, it means that a new record has been created and inserted into the database, so a flag is set to trigger a full reload of the list table view.
When the user returns to the list view controller, the viewDidAppear: method is triggered. In this method I examine the flags and either call
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
to reload the specific record if the record was updated, or tell the table view to do a full reload if there is an insert of a new record.
Finally I then remove the list controller as an observer of core data notifications because it is no longer interested.
I don't know if this is the recommended way to do this, but so far it's working for me.
You can try to reloadData before popViewController but you should post some code.
All UIViewControllers have a navigationController method. When you push a view controller to a navigation controller, that property is set to point to the navigation controller.
So, just call [self.navigationController popViewControllerAnimated:YES]; in the view controller.
Also, don't confuse views and view controllers. When you click save in the view, you should make sure that the save button calls a method on your view controller, which in turn talks to the navigation controller.
On tapping a row You are going to new view with appropriate information.
Here you perform some operation such as editing data.
So first save the changes on click on save button (By calling an IBAction) and in this IBAction method will check wheter (changes are successfully saved) then call
[self.navigationController popViewControllerAnimated:YES];
And ensure that table reload itself by updated databese (for this change array of data by calling database method in viewWillAppear method).

How to load a table view when coming to back with out selection index

I am using navigation controller and have table views inside views.
when i select any cell it it will navigate to another view. so,from there if i click back button it come sto previous view.But,it showing the cell which is selected previously. I dnt want this .it should not show which cell we selected previously.
Could any one help me how to get this.
Thanks.
From the apple docs : When the user selects a cell, you should respond by deselecting the previously selected cell (by calling the deselectRowAtIndexPath:animated: method) as well as by performing any appropriate action, such as displaying a detail view.
For more info see http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/ManageSelections/ManageSelections.html