iOS Swift - Using temporary UIView that can be cancelled - ios

I have a View Controller that is attached to a Navigation Controller (so any segue out of the View Controller maintains the view hierarchy of the Navigation Controller). How would I go about creating a temporary view that pops up from below that can be cancelled and does not conform to the Navigation Controller. For example, the 'Add Event' button in the Apple Calendar App, which brings up a screen that can be cancelled and brought back down.

You can use a UIPopoverController or you can just make a custom UIViewController and add it to the current view controller as a child view controller and present it modally without interfering with the Navigation controller.

Related

Dismiss all modals in iOS with Swift 4

I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.
I am able to dismiss a single view using
dismiss(animated: true, completion: nil)
but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.
I'm working with Swift 4.2 in Xcode 10.
The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.
The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.
From Apple Docs:
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
If you want to retain a reference to the view controller's presented view controller, get the value in the presentedViewController property before calling this method.
The completion handler is called after the viewDidDisappear(_:) method is called on the presented view controller.
try this
self.navigationController?.viewControllers.removeAll(where: {$0.isModalInPopover})

iOS - navigation controller back button

I'm developing an iPad App using storyboards. In this app when the user click on "preferences" appear a modal View. One button of this view send the user to another View Controller (but this view has an action bar to go back to his root view controller), but when user taps the action bar back button nothing happen (it's called navigationController popViewControllerAnimated), the user continue in the same view.
Can anyone help me??
Thanks.
UPDATE:
The code to handle the back button:
- (IBAction)btnBackTapped:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
I'm using Segue (from storyboard) to call this View Controller:
When the user click on "Meus Favoritos"
They will be redirect to this page:
The segue is with a Modal (from image one to two)...
When you are presenting a View Controller modally, it is likely not within a Navigation Controller, so probably the reference to navigationController in your code is nil, can you check that?
If you are presenting your View Controller modally this will work instead
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
However, if you actually want to use a Navigation Controller, you should embed the View Controller that is presenting the Preferences View Controller in a Navigation Controller and present the Preferences View Controller with a show segue instead of a modal one.

Show UITabBar while presenting a modal view

When a user taps on a UITabBar item, I would like to present a view controller modally, but I would also like the UITabBar to remain visible. When the user is finished with the modal view controller I want to dismiss it modally. Basically, I want to show one view controller on top of another and dismiss the top view controller with a modal animation, while keeping the UITabBar visible. I am thinking I have to do some sort of custom animation, but I cannot figure out how to make that work.
Anyone know how to do this for iOS 6 and iOS 7?
Modal segues coverup the previous navigation controller stack, so any existing tab, navigation, and tool bar controllers will no longer accessible. You'll either need to use a push segue to retain the existing tab bar, or add a new tab bar controller to the modal view.

UISplitViewController and Modal view controller presentation issues

I am having troubles with an application where I have a split view controller and would like to display a modal view controller over the top.
To test this, I have created a basic project which mimics the structure of my application. I have uploaded this to Github for anyone to download: https://github.com/CaptainRedmuff/SplitViewDemo
There are two main issues which I will detail below:
Issue 1:
When presenting the modal view controller in portrait orientation with the master view controller visible (as a popover I believe), the modal view controller is displayed underneath the master view controller. Any attempts to interact with the model view controller cause the app to crash.
Issue 2:
When presenting the modal view controller from the tab bar controller (in the master view controller), the modal view controller is automatically dismissed when the device is rotated to landscape orientation as the master view controller is removed from the hierarchy.
One possible fix I have found is to conform to the UISplitViewControllerDelegate method - (BOOL)splitViewController:shouldHideViewController:inOrientation: and return NO to force the master view controller to always be visible. This is not the behaviour that I want however so this is not a viable fix.
Considering that there is no way to programatically display or dismiss the master view controller, I am at a loss for alternative methods to present a view controller modally over the top of the entire split view controller.
Before presenting modal VC you must dismiss popover like:
[self.popover dismissPopoverAnimated:NO];
The issue occurred probably because UIPopoverController is added to the window instead of UISplitViewController.

What is the difference between Modal and Push segue in Storyboards?

Can someone explain to me what is the exact difference between modal and push segue?
I know that when we use push the segue gets added to a stack, so when we keep using push it keeps occupying memory?
Can someone please show me how these two are implemented?
Modal segues can be created by simply ctrl-click and dragging to destination but when I do that with the push my app crashes.
I am pushing from a button to a UINavigationController that has a UIViewController.
A push Segue is adding another VC to the navigation stack. This assumes that VC that originates the push is part of the same navigation controller that the VC that is being added to the stack belongs to. Memory management is not an issue with navigation controllers and a deep stack. As long as you are taking care of objects you might be passing from one VC to another, the runtime will take care of the navigation stack. See the image for a visual indication:
A modal Segue is just one VC presenting another VC modally. The VCs don't have to be part of a navigation controller and the VC being presented modally is generally considered to be a "child" of the presenting (parent) VC. The modally presented VC is usually sans any navigation bars or tab bars. The presenting VC is also responsible for dismissing the modal VC it created and presented.
Swift 3.0 and XCode 8.2.1 update
1. Push Segue
Push segue has been renamed as Show segue. To create push segue, the parent view controller needs to be embedded in navigation controller. The navigation controller provides navigation bar. Once you connect two view controller with push segue, the child view controller will automatically has navigation bar on top. The child view controller will be added on top of the navigation stack.
Push segue also provides default features. The child view controller will have a back button that gets you back to the parent view controller. You can also swipe right to pop the child view controller. The animation for push segue is like sliding pages horizontally.
While you are allowed to make a push segue from a view controller that is not in a navigation controller, you will lose all the features like navigation bar, animation, gesture etc when you do so. In this case, you should embed your parent view controller inside navigation view controller first and then make push segue to child view controllers.
2. Modal Segue
A modal segue (i.e. present modally), on the other hand, is presenting over the current view controller. The child view controller will not inherit navigation view controller so the navigation bar will be lost if you present modal segue from a view controller with navigation view controller. You have to embed the child view controller in navigation controller again and start a brand new navigation stack if you want it back. If you want to get back to parent view controller, you have to implement this by yourself and call dismiss from code.
Animation for modal segue is that the child view controller will comes up from the bottom of the page. The navigation view controller is also gone in this demo
The push view must be built in a navigationController.
Click on your master view, then in the menu bar choose:
EDITOR->embed in->navigationController
This is pushing controls using custom push and segue methods for storyboard
And Modal is way to navigate through views without using Storyboards.

Resources