As with the settings page, I have a UI that displays a list of parameters, one of which is a date. When the user presses the row containing the date, a controller displaying a UIDatePicker is pushed.
What is the best way to update the table row with the selected value of the UIDatePicker when the user presses the back button to go back to the list of parameters.
How about: have the picker's controller tell the table view's controller about the update (assuming that they're not already the same object), and have that controller call reloadRowsAtIndexPaths:withRowAnimation: on the table view itself.
Or is your question, how do you get the controllers to talk to each other?
Related
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.
i have a view which is fetching data from an Array and presenting the data in a tableview. This view has a navigation controller with a button in it. The button is meant to take you to another view for advanced searching. Let's say that in this new view i have a picker, when the user selects a value from the picker and clicks the back button in the navigation bar i want to get the value that the user selected. What is the best practice to do that? How can i send the selected value from one activity to the previous one?
Thanks in advance.
What you need here is reasoning a bit in terms of the Model-View-Controller design pattern.
Views should get their data through the model. So in your advanced search view, when the user selects some value, this value is stored in the model.
When you go back, the first view redraw itself by reading the current search value from the model.
There are other possibilities, like having the search view controller own a pointer to the first view and sending a message to it when the search value changes, but this is not very modular and is pretty fragile.
Use delegation. Write your own protocol like "PickerViewDelegate". then implement this protocol in your "main view" (which has table view). in PickerView just invoke [delegate somethingPicked:something].
I'm not sure, that search value is a model entity.
I have a UITableViewController and in the didSelectRowAtIndexPath method I create an instance of a UIViewController and push it on to the stack.
The UIViewController is meant to edit the content of the selected cell but how do I get the changes made in the ViewController transfered back to the TableViewController?
Cheers
The standard way to pass data back up the hierarchy is with delegation or even more simply through querying a property on the edit view controller when you want to get the edited data back.
Now, when it comes to edit view controllers you can design them to support both direct editing of 'live' objects, or a copy which will let you do a Save/Cancel model.
So what you want is for your edit view controller to edit some sort of ModelObject instance with various properties. These properties will correspond to the textfields or date-pickers etc. in the view. So you might have a Person with NSDate *dateOfBirth and NSString *name.
When you create the view controller and push it onto the navigation controller, you give it one of these ModelObjects to edit. You can either pass in an object straight from your model which will be edited 'live' as the user enters values, or a copy which will let you discard changes and implement a Save or Cancel workflow. For the latter you can add the Save and Cancel buttons yourself before you push the edit view which lets you handle the actions yourself without needing delegation.
So your edit view controller will set the properties on this object when the user enters a new value in a textfield or changes the date picker. For a live object these changes will be applied immediately to your model. For a copy, when the user hits Save you query the edit view controller for the object you passed in and merge/copy that back into your model. If the user hits cancel, you just discard the object.
Override the "parent" or table view controller's -viewWillAppear: method and reload the table view data there, using [tableView reloadData];.
When you go back to the table view controller from the edit view controller, the table view controller's -viewWillAppear: method reloads the data, which in turn calls the table view delegate methods.
You have to make sure that the two controllers 'share' data somehow. The easiest option is to have the first controller pass in the array (or just the selected object) that is selected in the table. The second view would then directly modify that array (or single object) and then when you dismiss the second view will show the modified data.
You might have to reload the table.
Makes sense?
I was wondering if with a UINavigationController, can you have a "+" sign, like the Contacts app, that adds a row to the main root view and has a default name as "Setup", then you can click on that row to go to one level below, change a value in a UIPickerview in the one level below UIViewController, and then press the back button and have that value from the UIPickerView be the name of the new row that was created?
Yes (though it's not very Apple-like UI behavior!)
You'd have to put some special logic in your table view data source to add the "Setup" row and go to the picker when that row was selected. The root view controller should implement the delegate from the picker to receive the new row's name, then call [self.tableView reloadData] to update the view.
A better practice would be to model the Contacts app and let the "+" button present a modal view controller from the bottom for your picker view. Look at the addButton implementation in SQLiteBooks or CoreDataBooks.
I have a ordinary UITableViewController inside a UINavigationController. The former includes a searchbar which is connected to a search display controller. I use the standard behaviour, i.e. when the user enters any character the search results table view overlays the normal table view.
Now, both table views act inside a navigation controller. If I select one item from the search results table view, a new uitableviewcontroller (with specific information about the item selected) gets pushed onto the nav stack. When I hit the back button on that controller, I observe a strange behavior: The section headers of the normal table view overdraw the section headers of my search results table view. They are displayed as if my normal table view is being displayed (I can see that from the number of rows between the headers, though the rows remain empty). The search result table rows are still being displayed.
This behavior comes from the fact that I reload the table view on viewWillAppear. I do this to react on changes in the database made by the user at some other point in the application or automatic background data updates. I already tried to poll if the recently displayed table view is being shown via
(self.tableView == self.searchDisplayController.searchResultsTableView)
but that statement is always false after I return to my normal table view controller.
The question: how can I poll the correct state of my table view to avoid the displaying errors?
The UISearchDisplayController class implements an active property. Guess what it's used for :-)
e.g. just check for (self.searchDisplayController.active) or ([self.searchDisplayController isActive]).