I'm implementing a datasource object for an UIScrollView. Is that part of the Controller, or part of the Model? I think Controller, but not sure. It delivers the data. But the data could be in sqlite3, files, from the net. So actually I would say it's not from the Data part, since it should be flexible to from where the data comes. What do you think?
The data source for any visual control should be your controller. Your controller should get/process the data from the Model and then hand it off to the view.
I would say it is actually neither. Your UIScrollView datasource is simply formatting your data for display.
Unless you have specific actions that perform "business logic", your UIScrollView datasource participates in the View.
The Controller would include logic that modifies or processes data in any way, your scrollview simply allows the data to be displayed.
Cocoa's MVC paradigm encourages both "model controller" and "view controller" objects. The data source object falls in the view controller category; it requests model objects from the data store depending on what UI element needs them, reformats the data a bit to fit , and passes it on to the UI. Usually the same object will also handle UI events and delegate methods.
Related
If we say that View and View Controller can be considered as View in MVVM, then shall we use Delegates in ModelView (which is for business logic).
Generally, if it's a view's delegate - put it in the View Model. If it's model-level delegate not related to the UI, implement it in the Model.
your question is pretty unclear, but I can still provide an outline / guideline for you.
Typically as your apps evolve with more complexity, you'll need view models for each of your views that can be customized and described by data. You want your view controllers to be clean and very readable, and as a result, you should only use view controllers as containers for your custom views. Your custom views can have a view model property with a didSet that allows it to modify and configure the view. For example, when I dequeue a cell from a tableView, I would give the (cell as? MyCustomCellClass)?.viewModel = aViewModel to make it extremely readable. You use delegates to handle business logic by setting delegates appropriately to communicate between a subview and a view, or from a tableViewCell to whatever controller is managing and extending the UITableViewDelegate or UITableViewDataSource. So all in all, your MVVM architecture will rely on custom View Models that you can use to configure your custom views, while you have controller objects managing business logic and handling the flow of data between things at a lower level with things at the higher level. If you have a specific example you'd like help with, please post some code. Hope this helped!
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.
I am new to Objective-c, I want to ask what is the different between view controller and view such as "UITableView" and "UITableViewController"?
What happen if I use UITableView instead of UITableViewController?
Thanks
You should look up the Model-View-Controller pattern in the Apple's documentation, since it is very important for using Cocoa. Basically, the idea in Model-View-Controller is a pattern for designing your class structure. Broadly, the model is where the application's data should be kept. The view is what controls the application's appearance and the controller is the place where the two are assembled. (Ideally, the view and the model classes do not even need to know about the other's existence).
Hence, the UITableView and UITableViewController are two different classes with two different purposes. The UITableView controls the appearance of the data and the UITableViewController "controls" the view (generally by passing it the correct data for display and layout). Since this pattern shows up again and again in Cocoa programming, you should take some time to become familiar with it.
They are two different things, they cannot be substituted for the other.
iOS follows the MVC design pattern, which stands for Model-View-Controller. The two classes you mention are 2 pieces of the overall puzzle.
The View is what gets displayed on the screen. That is its responsibility. So, the TableView is responsible for telling the phone what to render on the screen.
The View is also accompanied by the Controller. The controller decides what to do when something happens (user interaction, and other events that can happen at any time). So, the TableViewController is responsible for making the table do stuff (for example, telling the TableView what data to use for displaying on the screen).
So to sum it up, they are completely different, but they work very closely together in your application (you will almost always have 1 Controller for each View.
Well, the short answer is that one is the View and one is the Controller. Combine this with your data (the Model) and you have all the parts of MVC (Model - View - Controller).
Think of it this way, the UITableViewController controls the UITableview. They are complementary and they need each other to work.
Simple question here... Is it alright in terms of MVC design to observe a value in the model from a view (using Key-Value observing), and update the view's current location on the screen based on when the model's variable changes?
Is it okay to observe from the view object and have that object move itself when the Location variable inside of the model object changes?
Or is this against MVC because the view and the model are communicating in a sense?
You should tie it through a C, controller, item. Even if it means you're pulling in the state data from the model, and then having the controller set the view or the view read that data from the Controller.
The view and model should always be separated by a controller. That's MVC according to Apple. The reason is that even right now it may be straightforward for you to have the view reference the model's state - but the model could change in the future, and then you'd be stuck updating the view, when there's really no reason the view should be impacted. And the model should never update the view's position - it should really not have any idea of any details of display. That's the job of a controller, to control your views and move them around based on model data.
Think about it this way: the view should only know how to display things or interact with user I/O, a model should only know about the business logic with data that comes in over an interface of inputs and outputs. You should be able to run a model without a view even existing, instead you should be able to just have unit test type code that feeds those inputs and outputs. So something like moving a view around is completely out of the responsibilities of a model.
I am writing a fairly complex iPad app - my first bigger one.
This app has some custom UIViews that present fairly complex data, including a table. These views do not take up the whole screen, and there can (and likely will) be many of them on screen at any time (though only one would be in an "expanded" state where the table is shown).
Here's a basic example that should convey the basic principle:
Please note that these things are not supposed to be in popovers; instead, the FamilyViews expand to show their detailed data. (And please also note that this mockup was only created for the sake of this question and has little to do with how my interface is going to look; I know this is not good screen design)
I'm undecided on who to put as the delegate and datasource of these custom views:
Making the ViewController for the current screen delegate and datasource is unelegant, because it's not just one table that's part of the VC's main view.
Making the View itself the delegate and datasource seems a bit weird to me because it feels like giving the view too active a role; making it into a half-controller.
Making the underlying model object the datasource seems too tightly coupled, and also breaks MVC. And it doesn't answer the question of who should be the delegate.
I'm tending towards making each of these "FamilyViews" delegate and datasource for their own tables. Action on these tables will have to be coupled to the FamilyView's delegate (the ViewController), but that shouldn't be a problem, should it?
Anyone have some input on this?
Views should know how to paint themselves and layout their sub views, depending on their properties, and that's it.
You definitely should let a controller class be the delegate instead of the view itself.
The delegate controller doesn't have to be the view controller that displays the view, though. It could easily be a completely separate controller class that only knows how to handle what the view requires.