How to transition e.g. fade, from one view controller to another - xcode

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.

Related

How does one display a new view controller in the same Mac window?

I'm fairly new to Mac development and am slightly confused by the new "storyboard" feature in Xcode 6. What I'm trying to do is segue from one view controller to another in the same window. As of right now, all the different NSViewControllerSegues present the view controller in a new window, be it a modal or just another window. What I'd like to do is just segue within the same window, much in the same way one would on iOS (though an animated transition is not crucial). How would this be achieved?
If you provide a custom segue (subclass of NSStoryboardSegue) you can get the result you are after. There are a few gotchas with this approach though:
the custom segue will use presentViewController:animator so you will need to provide an animator object
because the presented view is not backed by a separate Window object, you may need to provide it with a custom NSView just to catch out mouse events that you don't want to propagate to the underlying NSViewController's view
there's also a Swift-only glitch regarding the custom segue's identifier property you need to watch out for.
As there doesn't seem to be much documentation about this I have made a small demo project with custom segue examples in Swift and Objective-C.
I also have provided some more detail in answer to this question.
(Reviving this as it comes up as first relevant result on Google and I had the same problem but decided against a custom segue)
While custom segues work (at least, the code given in foundry's answer worked under Swift 3; it needs updating for Swift 4), the sheer amount of work involved in writing a custom animator suggests to me that their main use case is custom animations.
The simple solution to changing the content of a window is to create an NSWindowController for your window, and to set its contentViewController to the desired viewController. This is particularly useful if you are following the typical pattern of storyboards and instantiate a new ViewController instance every time you switch.
However.
The NSStoryboard documentation says, quite clearly in macOS, containment (rather than transition) is the more common notion for storyboards which led me to look again at the available tools.
You could use a container view for this task, which adds a NWViewController layer instead of the NSWindowController outlined above. The solution I've gone with is to use an NSTabViewController. In the attributes inspector, set the style to 'unspecified', then select the TabView and set its style to 'tabless'.
To change tabs programatically, you set the selectedTabViewItemIndexof your TabViewController.
This solution reuses the same instance of the ViewControllers for the tab content, so that any data entered in text fields is preserved when the user switches to the other 'tab'.
Simple way with no segues involved to replace the current view controller in the same window:
if let myViewController = self.storyboard?.instantiateController(withIdentifier: "MyViewController") as? MyViewController {
self.view.window?.contentViewController = myViewController
}

Swipe gesture without messing the navigation bar?

This is hard to explain but i'll try my best. I have a Table View controller that leads to 10 View controller. All the View controllers have a navigation bar title (The titles are the 10 objects from the Table view controller). Now i want to add the Swipe Gesture for a easier navigation between the 10 table view items (Instead of going back to the Table view manually i want the user to be able to swipe to change from a view controller to another). HERE'S THE PROBLEM: When i add the Swipe Gesture and i connect it from one view to another, it asks if i want the action to be either: Push, Modal or custom. Now, if i choose one of them, it makes the navigation bar title disappear. I want to keep the title without messing up the connection from the table view to the views controller. Thanks.
You want a pageviewcontroller. Set up the pages to be your different view controllers
A pageviewcontroller essentially allows you to do exactly what you want to do without having to setup a new segue every single time. That way it can all happen under one navigation bar. If you've seen the twitter app, you know how you can scroll through your feeds? Same thing.
There are tons of tutorials on the web, but pageviewcontroller a can be a tiny bit tricky because they require some logic
Here's a slightly more advanced thing that might be useful to you:
https://github.com/cwRichardKim/RKSwipeBetweenViewControllers

Cocoa OSX custom widgets/controls

I want to know how can I create custom widgets/controls in Cocoa.
Not a full tutorial, but some guidance on what to start looking into. I'm confused by custom views, Core Animation, etc. I feel lost.
I see a lot of cool looking controls, like in Reeder App, or Sparrow etc. For example:
The left side is a collapsable menu that includes animations etc. How can I achieve something similar? I thought of using a WebView + HTML + JavaScript, but that doesn't seem like a very optimized solution.
Controls are views, so if custom views confuse you, you'll need to get that figured out before moving on to custom controls. Although you should really read the entire View Programming Guide, the section called Creating a Custom View will get you started on creating your own views. Try creating a simple view that draws a circle, for example, or the time.
When you've got views figured out, move on to custom controls. Most controls work about the same way. The user touches them, and the control responds by: a) tracking the user's input, b) changing its value, c) sending its action message to its target, and d) giving the user some feedback by redrawing itself. To get started, first make sure that you know how to use controls. Reading Control and Cell Programming Topics should help, and the section titled Subclassing NSControl covers (obviously) creating your own subclasses.
The example you provided is pretty clearly Apple's Mail.app. The view on the left side of the window might be an instance of NSOutlineView, or it might be a custom class. Either way, NSOutlineView would be a good starting point if you want to duplicate that functionality. NSOutlineView is a subclass of NSTableView, which in turn is a subclass of NSControl, which in turn is a subclass of NSView. Read Outline View Programming Topics for help getting started -- tables and outlines are extremely useful, but also more complicated to use than basic controls like buttons and text fields.
I know it's only a part of the UI, but I've recently coded something similar to the sidebar. If you look though the source-code it may give you some help on learning how to use custom controls and cells.
You can check it out on Github:
https://github.com/iluuu1994/ITSidebar

MVC design pattern in complex iPad app: is one fat controller acceptable?

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.

Simplifying a complicated Cocoa-Touch View Controller

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

Resources