This question is about a Cocoa app I'm working on but it could apply to anything using an MVC or related architecture.
Who is responsible for animations?
I can see two arguments:
1) Animation code should exist in a view (part of a view's presentation, how it draws itself) but be controlled by a controller (interpreting user input, etc).
2) Animations and their lifecycle should be managed completely by a controller and act on the views belonging to that controller.
I think first option is better because it would be fast if we can handle the events at view itself. Animation is most of the cases do not need additional data...so there is no need to reach to controller.
I think an animation is a modification of the model which is shown by the view. That's why I see the animation handling in the controller.
Related
I have done a lot of research on Youtube, websites and Stack Overflow, but couldn't find anything that worked. Hopefully, you can help me. I have view controllers in Xcode, and buttons on them that perform segues, to show the next view controller. But when it changes view controllers with the button performing a segue (show), it brings the next view controller up from the bottom of the screen. How do I change the transition (or add a transition) to make them fade into each other.
What you’re doing(the segue) is presenting the view modally. This is an Apple defined behavior which we get for free.
What you want is a custom view controller transition. Therefore you’ll need to implement it yourself.
Luckily, Apple has a great system built-in that makes creating custom UIViewController transitions easy. Although it will require some familiarity with iOS libraries and experience with animation logic.
You can check out this article.
I have a window that contains several rather complex views. Right now, I'm using a single NSWindowController to control the UI for the window and all the views. It's becoming a pretty huge class, since it's dealing with the details of each and every view.
The view behaviors are independent from one another though, so I see an opportunity to put the UI logic for each view into a separate controller.
According to the Mac App Programming Guide, this is exactly what view controllers are for:
Use view controllers to divide up the work for managing more
sophisticated window layouts. Your view controllers work together
(with the window controller) to present the window contents.
However, I can't find any documentation or examples on how this idea works in practice. Can I add multiple view controllers to the nib file in addition to the window controller?
If you add the view controllers to the nib, that's where they're going to be instantiated, and you'd add IBOutlets to the window controller (assuming that's the nib's File's Owner) in order to connect them.
In terms of memory, however, that scheme could become expensive, especially the more view controllers you have. You may want to instead consider lazily instantiating them in the window controller, (i.e., doing so only when needed), assuming this doesn't result in an objectionable lag before the view is presented for the first time.
Don't be afraid to try both approaches. One of them may be best for you.
In any case, I applaud you for your decision to factor out all that code into separate controllers. Very nice. Good luck to you in your endeavors.
I am building a complex iPad application; think of it as a scrapbook.
For the purpose of this question, let's consider a page with two images over it.
My main view displays my doc data rendered as a single UIImage; this because I need to do some global manipulation over them. This is my DisplayView.
When editing I need to instantiate an EditorView with my two images as subviews; this way I can interact with a single image, (rotate it, scale it, move it). When editing is triggered, I hide my DisplayView and show my EditorView.
In a iPhone app, I'd associate each main view (that is, a view filling the screen) to a view controller.
The problem is here there is just one view controller; I've considered passing the EditorView via a modal view controller, but it's not an option (there a complex layout with a mask covering everything and palettes over it; rebuilding it in the EditorView would create duplicate code).
Presently the EditorView incorporates some logic (loads data from the model, invokes some subviews for fine editing, saves data back to the model); EditorView subviews also incorporate some logic (I manipulate images and pass them back to the main EditorView). I feel this logic belongs more to a controller. On the other hand, I am not sure making my only view controller so fat a good idea.
What is the best, cocoa-ish implementation of such a class structure?
Feel free to ask for clarifications.
Cheers.
Huge fat controllers are fine.
If necessary, just break off some "purely logical parts" from it and shove them in other "helper classes". And use tricks like categories extensively where you can.
Definitely go with a HFC (huge fat controller) if that feels right.
Then, just get on your engineering bike and slim the hell out of it!
You should definitely not avoid the right structure, the good structure, the structure you want, just because one thing will be too big.
Just slim that big thing down by outsourcing concepts, going nuts with categories, etc etc - every trick in the book.
My belief!
Some reasons to wrap a viewcontroller around your view:
to use it in an Apple API that requires a viewcontroller (popover views, modal views, navigation bars, tab bars, ...)
because the view can be invisible for a while, and so it makes sense to clean it up in low memory situations. The viewcontroller then guards the data that needs to survive such an unload-reload cycle.
because you just like the MVC pattern
I think the second bullet justifies a viewcontroller for your editable content view and another one for your non-editable content view.
I have a main view (subclass of NSView) and as i'm new to cocoa, i'd like to know how to update the view in function of events.
I know there are many methods that take events such as -(void)mouseMoved:(NSEvent*)event or - (void)mouseClicked:(NSEvent*)event My algorithm to determine what to do is ready. I want to know where I should update the main view: is it in the -(void)mouseMoved:(NSEvent*)event or in the - (void)drawRect:(NSRect)dirtyRect. And if it is in drawRect, then how should i pass the information to it?
Thanks in advance!
Here's a quick explanation that will hopefully get you on your way:
Handle events
User actions are communicated to your views and windows by events (keyboard + mouse) and actions (events interpreted by buttons and other controls). Your views should react to these events and actions by updating the model, which are the lower-level data structures that represent whatever your program displays to the user. If Cocoa, the view typically communicates through a controller object to make changes to the model.
Invalidate display / trigger redraw
After you have updated your model, you need to inform the view that it needs to redraw. This can be done in several ways, but the simplest way to do it is -setNeedsDisplay:YES. This will ensure that at some point in the immediate future, your view will redraw itself to display the updated model data.
Draw
At some point Cocoa will call -drawRect: on your view. Inside -drawRect:, you should read the requisite data from your model and draw the necessary graphics. You shouldn't do any manipulation of the model in this method.
As I wire up my first fairly complicated Cocoa-Touch view I feel like I'm inadvertently slipping back into old procedural patterns and finding it difficult to shake them off...Though fully aware of many of the Cocoa (OO) design patterns I'm afraid I may be subverting them.
As such this view in question is quickly becoming unmanageable and I'm wondering if I might be approaching it the wrong way?!? The view is managed by a subclass of UIViewController. The view itself contains ±10 subviews. Some of these subviews "slide" in and out and contain their own subviews (controls, imageviews, etc) that slide along with them.
Without getting into too much detail I've found that I'm executing most (if not all, including animation) of my management code w/in the touchesBegan/Moved/Ended methods of my root View Controller. And it's become a mess of managing, setting & checking boolean properties. if (editingMode & panelAVisible).... if (editingMode & panelBVisible)... or *if (viewFlipped) { for (MyCustomView view in someArrayOfSubviews)} etc, etc... granted the UI of this app requires most of these views (or their contents) to be touched and moved by the user to different parts of the screen.
The main problems I'm trying to solve seems to be along the lines of: if viewA is present then you 3 views go hide (animated)...or, If viewB is touched then all objects contained in viewC are negative... etc.
Any clever (or rudimentary) OO approach to handling this? Perhaps make the subviews that contain views act as their own mini view controllers? I haven't been able to find too many (any?) examples of that though...
As you suggested at the end of your question, I would recommend having a subcontroller whenever you need logic for a particular subview. The point of a controller object is to keep track of state of the view and to encapsulate all that view logic that you were describing. Interface actions, such as if the user can move to a different screen, can invoke save logic, can create a new document, should be in the controller for that particular view. This will help maintain a separation of concerns between the various controllers and cut your convoluted logic down at the top level.
While it doesn't pertain to iPhone programming specifically, the book Cocoa Programming for Mac OS X contains good examples (especially in the chapter about how to do preference windows) of using subcontrollers and subviews in your application.
I think you should go along your last suggestion, make the subviews that contain views act as their own mini view controllers. Each (sub)view that presents a 'screen full of content' could/should be managed by its own view controller.
Animating between those views can be done with the build in navigation controller (you can actually hide the top bar of a navigation controller) such that you have the default slide animation. Otherwise you could indeed create your own animation while still using that navigation controller.
'The view itself contains ±10 subviews'. Some of these subviews "slide" in and out [..]'. These subviews you're talking about are perfect candidates for extraction from your one monolithic UIView.
The basic OO principle to use is how the navigation controller does it, by pushing and popping views on and off a stack. Each view pushed and popped is handled by its own view controller.
HTH
Edit: I now see you're not specifically talking about iPhone development. Still, have a look how its done there (especially the UINavigationController). You can still get the basic design idea