Objective-C: updating UITableView with recursive function? - objective-c

I am trying to re-call core-data in UITable using model view. I am in UITable in - (void)viewDidLoad method using getting some data from internet and setting them entities and showing them on UITable.It works normal ,but Now I am trying to use new addModel view and in this model view I can type user name in textfield and save it in person entity.But when model view disappears my table not updates,after re-lunching it updates but because of not running vievDidLoad again it doesn`t gets value form internet.
i thought that am I have to use some recursive function? But where must I put it?in UITable which function calls every time?

NSFetchedResultsController, the iPhone equivalent of NSArrayController, is probably what you need. As the docs say NSFetchedResultsController
optionally monitors changes to objects
in its associated managed object
context, and reports changes in the
results set to its delegate (see “The
Controller’s Delegate”).
so it should respond when you update an entity.

Related

Retain View Controller when popped from Navigation Controller using ARC

I have two table views and a detail view being managed by a UINavigationController. When a row is selected on the second table, it pops to a detailed view allowing changes specific data represented by the row. I need to be able to switch between the UITableView and the UIViewController without losing any of the data that might have been changed in the UIViewControllers (button selections, text values entered in fields, etc).
Basically, once the UIViewController is presented, one should be able to switch back and forth between the table and detail view without losing any data.
The problem is, when a UIViewController is popped from the navigation controller, that memory is automatically released, and since I'm using ARC, I can't just keep a pointer to that with a retain command in the UITableView.
I know that I could manually rebuild the view each time its corresponding table row is selected, but I feel that might be a messy solution. Another option I've thought of is keeping an array of pushed UIViewControllers and checking if the selected table row corresponds with an existing value before a new one is created, but that might also get messy.
Any suggestions?
Your final wish in this back and forth of view is what you stated in your question: you want to switch between view controllers without losing any information of the actions performed in these controllers.
But if you think at how MVC pattern works, you should consider a view controller as the glue logic between the view and the model. The view is not persistent, that's why it is legitimate for ARC to get rid of the owning view controller when the view is no more needed. Instead what you should persist while your app is working is the model data only: the model data will be shared between the involved view controllers, the view controllers will be recreated each time and the corresponding views will be updated based on the model data. The only reason why the view controller should be kept alive is when its alloc-init-loadView takes too much (e.g.: the view is OpenGL backed) but in such case I would suggest you to keep a strong reference to it in the AppDelegate and ask it to refresh the content when the model data is replaced.
So basically what you should do is:
- select the table
- extract the model data associated to the table, including all information relevant for the view controller
- push the view controller; save all view modifications to the model
- when the view controller is popped, the model data will be returned only
- next time, when you push the view controller again, you will restore the model and re-init the view controller.
This approach is not complicated and gives you the possibility to structure the app in a clean way. Tomorrow you can change your view controller structure (that its view and the logic) without any impact in the communication with the other view controllers as this managed by the model passing only.
There are a couple of solutions to this, just like you suggested.
The array solution is highly inefficient because of memory issues.
The second solution you proposed is a lot more elegant. Just write your own init method in that view controller and init the view controller with data from a plist file
If I'm reading the question correctly, you've got a tableView and a detailView that are driven by the same model data. When changes to the model data are made in the detail view, you want those changes to persist.
If you update the model based on the state of the controls when the detail view is popped, then those changes will persist and the changes will be visible the next time you drill back down into the detail view.
You don't mention what form the table data takes, but let's assume it's an NSArray of NSMutableDictionaries. When you tap the row, the didSelectRowAtIndexPath: method will need to hand the dictionary from that array index to the detail view controller through a property on the detail controller. The detail view controller will update the dictionary values in the method that dismisses it.
The way to think of this is using the model-view-controller pattern. The table and detail view data is stored in the model; the views present the data; and the controllers are responsible for updating the model and navigating between views.

Adding a new cell to a Table View from a different view

I was wondering if there is a way i could have a table view displayed on one view then when you hit the "add" button it would flip you to a second view where you would type in the name that you want the new cell's text label to say. Then you would hit a "done" button and it would flip you back to the first view where it would have the newest item. And you would be able to add however many cells you want.
Cocoa and Cocoa touch are based on an MVC pattern. What that means is there's separate layers each with responsibilities - the model, the view and the controller.
The model is the data and the operations on that data, the view is what you see and the controllers mediate between them.
So, in your example, you wouldn't add a cell from a different view. That violates the fundamental pattern. Instead, what would happen is the view where your adding the data would call to the model to add the item and the view would go away. Then, when it returns to the view that lists the items, it would query the model (which contains the new object) and the list would contain the object.
The two views are decoupled and they share the same model. It allows you to change interfaces and storage without breaking most of your app because they're decoupled.
For example, you could have a table view controller that gets it's list from querying your model class. Your model class could be a singleton ( [MyModel sharedInstance] ) that offers a method like:
NSArray* items = [model getItems];
That method could be backed by Sqlite (search for fmdb), CoreData storage, a simple file, or even in memory data like an NSMutableArray. Your UITableViewController implements the callback methods by calling into your model.
Then, you offer an Add button which calls this to modally show your AddItemController.
[self presentModalViewController:addItemController];
After the user supplies the data on the form and clicks the Done/Save button, you call your model to save the item which is a class with the data:
[[MyModel sharedInstance] saveItem:item];
That writes to your storage.
Then, upon return to your UITableViewController, in viewWillAppear, you re query the data and call for the table view to reloadData;
_items = [[MyModel sharedInstance] getItems];
[[self tableView] reloadData];
Now the table shows the data you just added.
There's other variations but that's a basic one with MVC separation.
I'd just like to add, putting this in plain words...
Whatever source that you use for your table to load cells from (an array, dictionary, class, you name it...) then you create the "add" button, make it push the new view controller, then when you press the "done" button on your navigation bar, add the object's property (the name text field info, or whatever you need) to the source you load your table view data from.

UISplitViewController Master / Detail communication

I just started playing with the UISplitViewController - I've cobbled together some code from various tutorials, but I'm having trouble seeing how to send data from the Master to the Detail. I'm creating an RSS reader just to illustrate to myself how it should work. I've parsed an RSS feed and populated the MasterViewController with a UITableView, but I'm stuck figuring out how to take a row click and load the corresponding article in a UIWebView in the detailViewController. Any tips are appreciated.
A good approach is to use delegates. That allows one view to call a callback provide by the other. In this case the detail view relies on the master existing so having it callback is fine. I would avoid letting them have direct references to each other and reading each others data directly.
What exactly does delegate do in xcode ios project?
Here's a tutorial with UISplitViewController that does just that (delegate between master/detail):
http://www.raywenderlich.com/1040/ipad-for-iphone-developers-101-uisplitview-tutorial
Specifically this section:
Hooking Up The Left With the Right
Time to play matchmaker and hook
these two sides together.
There are many different strategies for how
to best accomplish this. In the Split View Application template they
give the left view controller a pointer to the right view controller,
and the left view controller sets a property on the right view
controller when a row gets selected. The right view controller
overrides the property to update the view when the property is
updated. That works fine, but we’re going to follow the approach
suggested in the UISplitViewController class reference here – use
delegates. The basic idea is we’re going to define a protocol with a
single method – “selectedBotChanged.” Our right hand side will
implement this method, and our left hand side will accept a delegate
of somebody who wants to know about this.
Another approach would be to have a shared model - sort of like a singleton with notifications to trigger different views to update themselves based on either the data from the notification or querying the model in reaction to a model changes. This is sometimes better in an app with many views that don't rely on each other and just bubble up data in various ways (which is not the case here - the detail view relies on the master existing so a delegate is fine).

How to access methods/variables from swapped custom view

I've created a window that contains an NSSplitView in which case the right custom view has a view that I swap into at runtime. The custom view swapped in contains a NSTableView with data inside it. I have a search box in the main window of the application that I want to be able to constrain the rows of the table view with.
I have the code to do this and I know it works, but the code I have was tested with a search text box and table view that were on the same window scope. With the text search box now being in the main window and the table view being in a different custom view, I'm not sure how to get the text search box to call the relevant methods from the custom view's controller class, because I don't have direct access to these method anymore.
I'm sure this is a very beginner question, but any help would be appreciated. Thanks.
Have your main window controller pass the search query or filter predicate to a property of the content view controller.
You can give the main window controller a weak-referencing (assign) property that holds the current content view controller. Implement a custom setter that not only assigns to the backing instance variable, but also does the swap. That, any time it's time to do a swap, you simply say self.currentContentViewController = viewControllerToSwapIn, and when it's time to change the query/predicate, you pass it to self.currentContentViewController.searchQuery (having implemented the searchQuery property in the MainContentViewController class and made all your actual content-view controllers inherit from that class).

UITableViewController Dynamic Drill-Downs

In a table-view that contains say 10 cells, is it the case that we need to create 10 separate UITableViewControllers to handle the different views loaded by clicking on each of those 10 cells?
That doesn't seem very efficient - especially in situations where large amounts of data (and thus tables/menu) need to be displayed.
How can you write a dynamic UITableViewController, that can accept any data-set (like an Array) on the fly and display its contents - and do it in a recyclable manner, so that it can be recreated again and again for each cell that is clicked?
I have it mostly working in an app I'm building - the only thing I don't fully understand about the method is how the incrementing of the "CurrentLevel" works since it seems like the variable would just keep getting reset since the controller calls itself.
Anyhow, the concept is that every time someone clicks a cell, a new instance of the UITableView controller is called and a new level is generated and added to "the stack", and a navigation controller is able to track what is in the stack and allow you to browse back to the previously loaded views.