Better method to make pop up view - ios

Let's assume we want to show some popup view on our screen. When user clicks a button our view pops up. In popup view we have Close button that hide/remove view itself.
Which method should I use to do that kind of thing:
1.) After click on the button add popup view to my main view. Close button removes popup view from superview.
or
2.) Make popup view with alpha = 0 and after click a button change alpha = 1. Close button changes alpha to 0.
When I was adding and removing view by multiple clicking in buttons I have noticed that application started to slow down.
If you know good solution/method to do that kind of things (show view/views in another view) it would be very usefull.

Actually UIKit treats very-low alpha elements as hidden but hidden elements still participate in autoresizing and other layout operations associated with the view hierarchy. To save your performance i'd recommend to use addSubview/removeFromSuperview methods when show/hide your view.
You can also use ViewControllers with standard animation like:
let presentedVC: ViewController = self.storyboard?.instantiateViewControllerWithIdentifier("presentedVC") as ViewController
presentedVC.modalPresentationStyle = .OverCurrentContext
presentedVC.view.backgroundColor = UIColor.clearColor()
self.presentViewController(presentedVC, animated: true, completion: nil)
and when you tap Close inside your presentedVC use:
self.dismiss(animated: true, completion: nil)

Related

Convert modal view to fullscreen view

I have a modal view controller A presented at the top of the view controllers hierarchy.
Is it possible to make it fullscreen temporarily when a user presses a button? And then go back to standard modal look when used presses another button?
To clarify, I'm not talking about modalPresentationStyle = .fullScreen BEFORE A is presented, I need to present A in a standard way and then stretch it to be fullscreen when needed.
Although if I write pseudo code it would be something like this:
class A: UIViewController {
#objc func goFullScreen(sender: UIButton) {
// pseudo code:
// modalPresentationStyle = .fullScreen
// go fullscreen, block `drag-to-dismiss` gesture, remove `cornerRadius`, set `self.view.frame = UIScreen.main.bounds`
}
#objc func cancelFullScreen(sender: UIButton) {
// pseudo code:
// modalPresentationStyle = .pageSheet
// return to the standard look of a modal view controller
}
}
I found UIAdaptivePresentationControllerDelegate.presentationControllerShouldDismiss method that intercepts drag to close gesture, but I don't see any way to go fullscreen.
Picture of what I am talking about:
ps. I know I can make a custom container view controller with a custom transition delegate but I'd like to know if it's possible to implement such behaviour with system classes because I basically need just to flip modalPresentationStyle property with some interpolation animation...
Also on the right I hide/show some UI elements, but still it's the same view controller

Is it possible to prepare/reset a scene before it is shown / before viewDidAppear / viewDidLoad?

I am having a viewController with a couple of animated buttons, when the user presses a button the background is blurred (animation) and a menu to choose a couple of things (which all go to a new viewController) is presented.
So basically there is a scene, the user opens the menu, the scene is blurred except for the menu and the user presses a button and another viewController is shown programmatically with a crossDissolve. This is how I show the new controller:
let storyboard = UIStoryboard.init(name: "Timer", bundle: nil)
let vc = storyboard.instantiateInitialViewController()!
vc.modalTransitionStyle = .crossDissolve
present(vc, animated: true, completion: nil)
So far so good, but I am not able to reset the original scene (basically to just remove the blur and reset the animated buttons). I have a function in it called setupScene() which prepares everything for the app start (some buttons are hidden, the blur has an alpha of 0, etc....).
I just dismiss the new viewController like this:
dismiss(animated: true, completion: nil)
And than the original scene with it's last state (blurred etc.) is shown again.
So when the new viewController is presented I would like to reset everything in the original viewController in the background, so that when the new viewController is dismissed the old scene is already reset, but this doesn't work. I tried to move the setupScene() function in viewDidAppear, but either in viewDidAppear or viewDidLoad first the new viewController is dismissed showing the original viewController in it's last state with the blur again and then the setupScene() runs to reset everything (which obviously works fine).
Is there a way to reset everything in the background while the new viewController is shown or while the crossDissolve is running?
This sounds like a good case for viewWillAppear. This is a lifecycle method that is called when the visibility of a view controller's views change. viewDidLoad is only called once.
There are several solutions to this, depending on how fancy you want to get.
Based on what you describe I think the first thing to try is to take advantage of that completion parameter in dismiss(animated:completion:)
It's a callback to your code once the dismiss is completed. This will allow you to reverse your animation.
The callback takes no parameters.
So, if your setupScene() method does what it says,
dismiss(animated: true, completion: {
setupScene()
})
should do it.

Swift - Without storyboard , how do I make a modal popup?

I didn't use a storyboard and I'm having trouble finding resources on programmatically making a modal popup ( it'll be a form with white background that takes up the bottom half of the screen) after you press a button. The previous view would be disabled until you exit out of this modal popup.
Would this modal popup have its own view and view controller? How would I make the popup appear and after you exit, you give the control back to the original view controller?
Thanks?
let rateViewController = RatePopupVC()
rateViewController.modalTransitionStyle = .crossDissolve
rateViewController.modalPresentationStyle = .overCurrentContext
rateViewController.item = item // In case you want to transfer some data
self.present(rateViewController, animated: true, completion: nil)
Would this modal popup have its own view and view controller
Yes. Configure your view controller and its view, and present it with present and dismiss it with dismiss. You can add custom transition animation and custom positioning of the view.

Present Modal View in Detail View in UISplitViewController

I want to make a behavior like contacts app in iPad with landscape mode.
I'm expecting that a Modal shows in a Detail view when I click upper right add button.
but now if I click upper right add button, the Modal shows in all screen.
what method should I use? showDetailViewController? or presentViewController? I don’t know how to show Modal in only Detail View.
Firstly you need to set detail view controller's property definesPresentationContext = true. So now it defines presentation context. By default view controllers doesn't pay attention to the current context when they are presented therefore you must do viewController.modalPresentationStyle = .CurrentContext
That's how complete method looks like
func adaptivePresentViewController(viewController: UIViewController) {
let detailVC = splitViewController!.viewControllers[1]
detailVC.definesPresentationContext = true
viewController.modalPresentationStyle = .CurrentContext
detailVC.presentViewController(viewController, animated: true, completion: nil)
}

Proper way to present UIActivityViewController inside UINavigationController inside popup

Suppose I have a UINavigationController inside a UIPopup. From there, I try to present a UIActivityViewController, by pushing it into the view controller.
if let navigationController = self.navigationController{
navigationController.pushViewController(activityViewController, animated: true)
}else{
self.presentViewController(activityViewController, animated: true, completion: nil)
}
The code executes without errors, however:
The displayed UIActivityViewController is corrupted and some text is not visible. (See image)
While pushing the view, part of the screen flashes when the popup resizes to accommodate the view (the popover is in the right side of the screen, and a ~150px vertical strip becomes brighter on the left)
As far as I know, I do not break Apple's Human Interface Guidelines by presenting the view this way. If so, what can be done so the view displays flawlessly?

Resources