iOS 8 Share Extension custom view controller size - ios8

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:

Related

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.

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

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.

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.

How to set size of UITableView inside Interface Builder?

Is it possible to change the frame of UITableViewController's UITableView frame inside Interface Builder? I want to make my table, which I instantiate in IB, a little bit narrower.
When you have create your tableViewController in IB, if you then go to the section on the right of the screen where all the options are set size to "freeform" then drag it to whatever you like. When you init it it will then get this frame. Unless it is within a container controller.
The best way to do what you are after is to create a viewController and add a table view to its view. Make the table view narrower that the main controller view and wire it up to an IBOutlet on your controller. If you then make your controller implement the and methods you will be able to use your table view exactly as you want to.
Hope this is of help to you, if this is unclear or you would like any extra help, let me know :)
You can change it in IB but unless you customize your view controller somehow, it will set it be full screen (module enclosing controllers like nav, tab bar, split view, etc.) That's just the way view controllers work.
From the Apple docs:
When a view controller is displayed on screen, its root view is
typically resized to fit the available space, which can vary depending
on the window’s current orientation and the presence of other
interface elements such as the status bar.
You can create another UIView to hold your table view and then have more control over the table view sizing, But then you won't be a table view controller and will have to implement some of the things that table view controller provides you, e.g., deselectRowAtIndexPath on viewDidAppear.

Resources