What are definesPresentationContext and providesPresentationContextTransitionStyle - ios

ViewController has definesPresentationContext and providesPresentationContextTransitionStyle,
but have no idea about how they work.
I watched the WWDC2011, but I'm still confused about these two things.
Could anyone explain this, preferably with a simple demo?

Both properties are used for view controller containment, and provide child view controllers the option to override the presentation context or presentation style of the window's root view controller. For reference, here is the relevant WWDC presentation that provides an explanation of both:
https://developer.apple.com/videos/play/wwdc2011-102/
definesPresentationContext is used to decide which view controller will determine the size of the presented view controller's view:
When a view controller is presented, iOS starts with the presenting
view controller and asks it if it wants to provide the presentation
context. If the presenting view controller does not provide a context,
then iOS asks the presenting view controller's parent view controller.
iOS searches up through the view controller hierarchy until a view
controller provides a presentation context. If no view controller
offers to provide a context, the window's root view controller
provides the presentation context.
If a view controller returns YES, then it provides a presentation
context. The portion of the window covered by the view controller's
view determines the size of the presented view controller's view. The
default value for this property is NO.
providesPresentationContextTransitionStyle is used to decide which modal presentation style should be used when presenting a child view controller:
When a view controller’s definesPresentationContext property is YES, it can replace the transition style of the presented view controller with its own. When the value of this property to YES, the current view controller’s transition style is used instead of the style associated with the presented view controller. When the value of this property is NO, UIKit uses the transition style of the presented view controller. The default value of this property is NO.
For complex child view controllers such as UISearchController, it's a good idea to have these set to true, the default value is false.

definesPresentationContext is related to child view controllers which in storyboards are represented by Container View. So, this option influence a presentation of a new UIViewController from a container view.
providesPresentationContextTransitionStyle is related also to child view controllers and will take effect only when definesPresentationContext is true

Related

Loading View Controller from another View Controller inside Container View

I'm developing an app for iOS.
I want to have a view controller (called child) that appears inside another view in my main view controller (called parent).
I managed to do this by adding a container view which embeds the child view controller successfully.
In my child view controller I have a button that opens another (3rd) view controller.
I want this screen to open within the bounds of the view container - but it opens on a full screen.
Is there a way I can define the view container in a way that all segues inside of it will show inside its bounds?
definesPresentationContext - a UIViewController's property that might be helpful here.
A Boolean value that indicates whether this view controller's view is covered when the view controller or one of its descendants presents a view controller.
https://developer.apple.com/reference/uikit/uiviewcontroller/1621456-definespresentationcontext
Set the child's property to true:
childViewController.definesPresentationContext = true
Also, before presenting the viewController (3rd), set its modal presentation style:
viewControllerToBePresented.modalPresentationStyle = .overCurrentContext
Hope this helps!
Try this post. It might help for adding viewcontrollers within bounds.
http://khanlou.com/2015/04/view-controllers-in-cells/

What is the difference between the modal presentation style "over current context" and "over fullscreen"?

I wonder what the difference between current context and over fullscreen is?
When I switch between them I don't see any changes in my app. All the animations look the same etc.
There aren't any visual differences if you are presenting a view controller from a view controller that is already in full screen mode. However, if the presenting view controller isn't in full screen mode, the current context will make a different. For example:
Left: before present, the current view controller is not in full screen mode
Middle: presenting a new view controller with full screen
Right: presenting a new view controller with current context
A full list of comparison of different presentation mode available here on Github.
fullScreen:
The presented view covers the screen (fullscreen).
currentContext:
The UIModalPresentationCurrentContext style covers a specific view controller in your interface. When using the contextual style, you designate which view controller you want to cover by setting its definesPresentationContext property to true.
When presenting a view controller using the
UIModalPresentationFullScreen style, UIKit normally removes the views
of the underlying view controller after the transition animations
finish. You can prevent the removal of those views by specifying the
UIModalPresentationOverCurrentContext style instead. You might use
that style when the presented view controller has transparent areas
that let underlying content show through.
Read more about presenting viewControllers here.

source view controller vs. presenting view controller

I'm reading a book that states that source view controller is not necessarily a presenting view controller. The source VC is the one that calls presentViewController:... method, and the presenting VC(it's view) is the one that gets obscured by a presented VC view. I can't think of a single example in which the presenting VC is not the same as source VC. Please provide some. Thanks
Text from book:
“Original presenter:
The view controller to which presentViewController:animated:completion: was sent. Apple sometimes refers to this view controller as the source; “original presenter” is my own term.
The presented view controller is set as the original presenter’s presentedViewController.
Presenting view controller:
The presented view controller’s presentingViewController. This is the view controller whose view is replaced or covered by the presented view controller’s view. By default, it is the view controller whose view is the entire interface — namely, either the root view controller or an already existing presented view controller. It might not be the same as the original presenter.
The presented view controller is set as the presenting view controller’s presentedViewController. Thus, the presented view controller might be the presentedViewController of two different view controllers.”
I was asking myself the same question when learning about view controller transitions, specifically when trying to understand the animationControllerForPresentedController:presentingController:sourceController: method from the UIViewControllerTransitioningDelegate protocol. The struggle was about the difference between the presentingController and sourceController arguments.
I found the answer in the View Controller Programming Guide. You can find the following in the Presenting View Controllers Modally section:
The view controller that calls the
presentViewController:animated:completion: method may not be the one
that actually performs the modal presentation. The presentation style
determines how that view controller is to be presented, including the
characteristics required of the presenting view controller. For
example, a full-screen presentation must be initiated by a full-screen
view controller. If the current presenting view controller is not
suitable, UIKit walks the view controller hierarchy until it finds one
that is. Upon completion of a modal presentation, UIKit updates the
presentingViewController and presentedViewController properties of the
affected view controllers.
This means that the 'source' view controller concept is not something randomly created by the author of the book you mentioned.
I'm afraid the book you're reading may have made a complex subject even more complex by adding the so-called Source View Controller to the whole mix of names.
For starters, there is no such concept of a "Source" in View Controllers. You have a parentViewController and childViewControllers only when talking about Container View Controllers. And you have a presentingViewController and a presentedViewController only when talking about presenting View Controllers modally.
You also have View Controllers whose main purpose is to manage other View Controllers, namely the Navigation Controller, the Tab Bar Controller, the Split View Controller and the Popover Presentation Controller. So any given View Controller may query itself to know if it is "attached" to a Navigation Controller, for instance.
What I'm guessing your book is implying is that a Source VC would be the one that makes another VC appear on screen. In this sense, it is right. The "source" may be different than the presenting VC. Take this snippet:
[self presentViewController:aViewController animated:YES completion:nil];
In the example above, the presenting VC is also the "source" VC. But here:
[someViewController presentViewController:anotherViewController animated:YES completion:nil];
We are calling the method on some VC lying somewhere passing yet another VC as argument. So in this case the presenting VC is someViewController and the presented VC is anotherViewController. Should this line of code be inside a third VC, then said third VC would be the "source".
But that's the thing! This last snippet of code may not even be inside a View Controller in the first place, so it's a bit odd to think about "source VCs".

iOS View controller's view alpha

Can I reveal the underlying view (or the view at the back of a view controller), by making a view controller's view transparent? I tried and it just fades to black and doesn't reveal anything behind it.
Reason?
EDIT:
Okay, this question needs more context.
I have a view controller. Now I am going to present another view controller(simple presentation of view controller, modally). After the new view controller has been presented, I am making its view transparent with alpha=0. Why does it not reveal the underlying view controller's view?
Will using the iOS 7 Transition API help?
If you present your view controller modally (using presentViewController:animated:completion:) then the presenting view controller's view will be removed removed from the window, therefore you cannot see through your presented view controller to the presenting view controller. You might want to use child view controller: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html
Alternatively, you can present your view controller inside a new UIWindow.
You cannot see the original view controller because you use -presentViewController:animated:completion: which will hide the presenting view controller after the animation finished.
You can set the modalPresentationStyle to one of UIModalPresentationOverCurrentContext, UIModalPresentationOverFullScreen and UIModalPresentationCustom before you called 'presentViewController:animated:completion' so that the underlying presenting view controller will not be hidden.
If you would like to have the same background image showing below all UIViewController you can add a UIImageView to the [UIApplication sharedApplication].window in the applicationdidfinishlaunching method

Presenting/dismissing modal view controller with custom animations does not display presenting view controller underneath

I have implemented a view controller which provides a navigation structure similar to UINavigationController. It is using view controller containment. All view controllers are added as children.
When I present a modal view controller from a view controller within this navigational flow, the underlying view disappears during the custom transition and the user is left viewing the Window view below.
[UIView animateWithDuration:0.35 animations:^{
self.view.transform = CGAffineTransformMakeScale(0.4, 0.4);
self.view.alpha = 0.0;
} completion:^(BOOL finished) {
[[self presentingViewController] dismissViewControllerAnimated:NO completion:nil];
}];
This is a very jarring experience. Previously this animation would shrink the modal view controller's view and fade it into the presenting view controller's view underneath. As I stated before, now the user is exposed to the view of the Window (which currently has not had an color values set).
Refering to the View Controller documentation I feel as though I have set all the right fields, however, something is incorrect.
A view controller presents another view controller when it wants that
view controller to perform a task. The presenting view controller is
in charge of this behavior. It configures the presented view
controller, receives information from it, and eventually dismisses it.
However, while it is being presented, the presented view controller’s
view is temporarily added to the window’s view hierarchy.
My presenting view controller is my custom navigation controller, the presented view controller is a modal view controller that allows the user to compose a conversation. My application's window root view controller is correctly configured to my custom navigation controller.
I also read some more about presentation context and have configured my custom navigation controller as having definesPresentationContext as YES.
When a view controller is presented, the portion of the screen that it
covers is defined by a presentation context provided to it by another
view controller. The view controller that provides the presentation
context does not need be the same view controller that presented it.
Figure 1-15 shows the same view controller hierarchy that is presented
in Figure 1-14. You can see that the content view presented the view
controller, but it did not provide the presentation context. Instead,
the view controller was presented by the tab controller. Because of
this, even though the presenting view controller only covers the
portion of the screen provided to it by the tab view controller, the
presented view controller uses the entire area owned by the tab view
controller. Within my custom navigation controller I have not
overriden any methods related to presentation or dismissal of view
controllers. All of the child view controllers that are added are all
added as childViewControllers and their views have been added to this
custom navigation controller.
Why would a custom transition show the Window's view instead of
respecting the custom containment view controller which provides the
presentation context?
Why would the traditional transition animations work as expected?

Resources