How to drag a View Controller on top of a View Controller? - xcode

I have a View Controller that is presented when you first open the app, and I have another controller that can be shown on screen if you tap a button at the top of the screen. However, instead of doing it this way I was wondering if I can either drag the view down or tap the button and have an animation take care of that.
I have tried doing this with a PageView Controller, but this doesn't show the effect I wanted as it simply translates over to the next view and doesn't actually keep the initial view fixed in place while the second view slides over it.
Also, instead of a view controller would a view initially placed out of bounds in the main View Controller work? Thanks in advance!

You could use a side menu like MMDrawerController that has 4 type of animations for presenting the viewController.
Or you can create your custom UIView (not viewController) even using Interface Builder and animate that screen yourself. The animation can be started using UIScreenEdgePanGestureRecognizer.

Related

How to move View Controllers on the Storyboard?

How can I arrange View Controllers on a Storyboard in Xcode's Interface Builder? When I try to select a View Controller, the mouse pointer grabs a view inside it instead.
Well, it wasn't obvious, at least for me. You should drag the white bar above the View Controller (the bar that contains the First Responder). It works even on low zoom levels!

macOS/ Xcode / Swift 3, how can I have a storyboard scene inside a NSScrollView?

I am new to storyboards and just learning swift. My document based app has a main document view where all the action is (user mouse clicks, keyDown, etc). It's size can vary based on either user menu command or model state changes. It also has subviews that may come and go. This needs to be the document view of an NSScrollview.
This document view needs its own view controller.
Starting with the main storyboard if I add a scroll view to the main view controller view, I can set my custom view to be the document view. But there doesn't seem to be anyway to give it it's own view controller, within the storyboard paradigm.
Previously, (under objective c, if that matters), I was able to create my document view and it's view controller in a XIB, then in code assign this document view to the NSScrollview's document view.
Presumably, I could still do this in code in Xcode 8/Swift 3, but isn't there a way to do it with storyboards?
Added Later: I seem to get close to what I want by replacing the scroll view's document view with a container view. I'm using a centering clip view, and apparently the container view cannot have constraints, or it defeats the centering!
I can then drag a new view controller onto the container view. The new view controller and it's view can be my custom view controller and it's custom view.
This looks like it will work OK, so far, but it seems a bit of a kludge to me. Is this the standard way to embed a custom view controller with its view in an NSScrollView?

UIPresentationController changes size when another view controller is displayed on top of it

I am presenting a modal view controller using UIPresentationController. I am setting the frame of presentedView less than the containView's bounds using following method:
override func frameOfPresentedViewInContainerView() -> CGRect {
let myDX = (self.containerView!.bounds.width - 600)/2
let myDY = (self.containerView!.bounds.height - 600)/2
return self.containerView!.bounds.insetBy(dx: myDX, dy: myDY)
}
Everything works great unto this point.
Now, I present another view controller modally (default not custom) on top of the currently displayed modal view controller which takes up the entire screen. So, I have a custom modal view controller underneath the default modal view controller that covers the entire screen.
The problem is when I dismiss the top view controller thats covering the entire screen, my custom view controller shows up covering the entire screen as well. I want my custom view controller's size to remain the same (smaller than containerView). Is there any way that I can achieve this.
Any help would be appreciated
I encountered the same issue. I couldn't solve it by adding constraints, and -[UIPresentationController containerViewWillLayoutSubviews] is called too late (after the dismiss animation is completed).
After some time I figured out that the problem seems to be that the presenting controller view is being removed from the view hierarchy when you present with the default UIModalPresentationFullScreen presentationStyle and added again with a full screen size when it has to be shown again.
In iOS 8, you can use UIModalPresentationOverFullScreen as the presentationStyle when presenting from the smaller controller. The system will not automatically remove the presenting controller's view then. (-[UIViewController viewWillDisappear:] and such, doesn't get called on the presenting controller when you do this though)
You can also use UIModalPresentationCustom which is available in iOS 7, but then you'll have to provide your own transition animation.

iOS 8 Share Extension custom view controller size

I'm building a share extension for my iOS app and I can't use the default SLComposeServiceViewController, so I created (in the storyboard) a basic UIViewController and embedded in a navigation controller. I get to present it, dismiss it etc but it's always full screen. I would like to make it look more like a dialog.
I have tried using self.preferredContentSize on my view controller, tried Use Preferred Explicit Size on the navigation controller in Interface Builder, but it doesn't work.
This can be done easily and directly using the storyboard but is not immediately obvious. There is no need for multiple view controllers.
Create your own view controller class inheriting from UIViewController.
In the MainInterface.storyboard change the class of the view controller to your new class
In the storyboard you can simply draw your UI - but here is the trick. You need to understand that the storyboard view will fill the screen and by default the view has already been created with a clear background. You simply need to create a view inside of the main view. You can set auto layout constraints to size this view and position it (e.g. centered horizontally and vertically). You can also use size classes to cause this inner view to fill the screen on compact layouts. Connect the controls from the inner view to your view controller in the usual way by control-dragging
In you custom view controller you can refer to self.extensionContext to read and complete the share action. Refer to the code in the template ShareViewExtension
Ok I spent a long time trying to figure this out. For whatever reason you can't set the view size like you can with the action extension. It will always go full screen (even on iPad). So a way around this is to make multiple view controllers. Make the first view controller hidden so the user doesn't notice that there is a full screen view controller present (And yes, in a share extension the first hidden view controller actually hides completely so the user doesn't even know it was presented). Then present your actual view controller using the hidden view controller. This way you can present it any way you like and set the size etc.
In my case I actually made my hidden view controller have a UIEffectView so I can have a nice blur animation in the background and then present my actual view controller over it.
Here is a picture:

how to get the Bar Button Item from Split View Controller without rotating the device?

I am developering in iOS 5.1 and is pretty happy with these methods in UISplitViewControllerDelegate
splitViewController:willHideViewController:withBarButtonItem:forPopoverController
splitViewController:willShowViewController:invalidatingBarButtonItem:
however, now I notice that these two methods will be only called when the device is rotating and thus the orientation changes. What I am trying to do is to segue(replace segue) my detail view controller to another one. In the new detail view controller, I will always hide the master view controller even in landscape and therefore I need the button.
Without the delegate being called of these two methods, how can I get the button?
If you are hiding your master view controller even in landscape (by means of split view controller delegate), the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: will be called, so you can safely put your code there.

Resources