func displayPopover() {
let popController = UIViewController()
popController.view.backgroundColor = .red
// set up the popover presentation controller
popController.modalPresentationStyle = .popover
popController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.up
popController.popoverPresentationController?.delegate = self
popController.popoverPresentationController?.sourceView = self.view
popController.popoverPresentationController?.sourceRect = CGRect(x: 100, y: 100, width: 100, height: 100)
// present the popover
self.present(popController, animated: true, completion: nil)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle {
// Return no adaptive presentation style, use default presentation behaviour
return .none
}
It displays the popover like any other view controller, sliding from the bottom displaying a red screen.
To get the "popup" effect:
1.You should make viewController in storyboard and then add view inside it like this(also add constraints):
2.You should declare the popover like this:
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("popupID") as! PopUpViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMoveToParentViewController(self)
3.Now you should make the background darker and transparent like this self.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.8) in viewDidLoad()
4.And to open it(it also animates it slightly):
self.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
self.view.alpha = 0.0;
UIView.animateWithDuration(0.25, animations: {
self.view.alpha = 1.0
self.view.transform = CGAffineTransformMakeScale(1.0, 1.0)
});
As per documentation
In a horizontally regular environment, a presentation style where the content is displayed in a popover view. The background content is dimmed and taps outside the popover cause the popover to be dismissed. If you do not want taps to dismiss the popover, you can assign one or more views to the passthroughViews property of the associated UIPopoverPresentationController object, which you can get from the popoverPresentationController property.
In a horizontally compact environment, this option behaves the same as fullScreen.
For iPhones popOver will behave same like fullscreen and for iPad it will be displayed in a popover view.
Related
I am trying to create number pad in iPad using popover view controller. Everything is achieved but there is a shadow beneath the pop view. I tried to remove that shadow but nothing worked for me. Here is my code which presents pop over view in my view controller.
let vc = self.storyboard?.instantiateViewController(withIdentifier: "PopOverVC") as? PopOverVC
vc?.modalPresentationStyle = .popover
vc?.preferredContentSize = CGSize(width: 280, height: 425)
vc?.delegate = self
if let popoverPresentationController = vc?.popoverPresentationController {
popoverPresentationController.permittedArrowDirections = [.down, .up, .right, .left]
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = txtNumber.frame
popoverPresentationController.delegate = self
if let popoverController = vc {
present(popoverController, animated: false, completion: nil)
}
}
Can anybody help me removing the shadow? Thanks in advance!!
I am trying to lay out a popover view when a button on current view is pressed. This works fine with following code but problem is that the popover view does not take the size from .preferredContentSize.
IngredientVC.preferredContentSize = CGSize(width: 200, height: 300)
Popover view has height and width of current view. How do I make Popover view smaller size please?
#IBAction func actionIngredients(_ sender: Any)
{
// Load and configure your view controller.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let IngredientVC = storyboard.instantiateViewController(
withIdentifier: "testViewIdentifier")
//let IngredientVC:testViewController = testViewController()
// Use the popover presentation style for your view controller.
IngredientVC.modalPresentationStyle = .popover
IngredientVC.preferredContentSize = CGSize(width: 200, height: 300)
// Specify the anchor point for the popover.
//IngredientVC.popoverPresentationController?.barButtonItem =
//optionsControl
//let popovercontroller = optionsVC.popoverPresentationController
IngredientVC.popoverPresentationController?.delegate = self
IngredientVC.popoverPresentationController?.sourceView = self.view
IngredientVC.popoverPresentationController?.sourceRect = CGRect(x:self.view.frame.width/2, y: self.view.frame.height/2,width: 200,height: 300)
IngredientVC.popoverPresentationController?.permittedArrowDirections = [.down, .up]
// Present the view controller (in a popover).
self.present(IngredientVC, animated: true)
}
Note: I have popover view controller in Storyboard with Simulated Metrics size as "Freeform".
I figured out that all I needed was following function -
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle
{
return UIModalPresentationStyle.none
}
I have an options button (that 3 vertical dotted button) on top of the view controller.
When I click that button, A list view should appear like in many other apps like WhatsApp...
I really don't know how to position it always near to the button programmatically.
Placing at the left-bottom of an existing view is quite easier:
func placeSubView(existingView: UIView)
{
let desiredWidth = CGFloat(50.0)
let desiredHeight = CGFloat(35.0)
let (x, y) = (existingView.frame.origin.x - desiredWidth, existingView.frame.origin.y + existingView.frame.size.height)
let desiredView = UIView(frame: CGRect(x: x, y: y, width: desiredWidth, height: desiredHeight))
existingView.superview?.addSubview(desiredView)
}
UPDATE:
In case you are looking for popupo menu like view, you should search about UIPopoverPresentationController.
Something like this.
Use this method and make PopoverViewController a table view controller if you want a list.
#IBAction func displayPopover(_ sender: UIBarButtonItem) {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "PopoverViewController")
vc.modalPresentationStyle = .popover
let popover: UIPopoverPresentationController = vc.popoverPresentationController!
popover.barButtonItem = sender
present(vc, animated: true, completion:nil)
}
I am trying to add a view controller from top for that I have created a custom animation which works correctly. However, the background color of the view controller which is being added is setting to black, where as I just want it to be transparent so that the view controller below can be visible.
Here is the code to add custom animation:
let vc = Global.sharedInstance.storyboard.instantiateViewController(withIdentifier: "AnimationViewControllerID") as! AnimationViewController
vc.view.backgroundColor = UIColor.clear
vc.personName = name
let begin = CGRect(x: 0, y: -vc.view.frame.height, width: vc.view.frame.width, height: vc.view.frame.height)
let end = CGRect(x: 0, y: 0, width: vc.view.frame.width, height: vc.view.frame.width)
self.present(vc, animated: false) { () -> Void in
vc.view.frame = begin
vc.view.alpha = 0.5
vc.view.backgroundColor = UIColor.clear
UIView.animate(withDuration: 1, animations: { () -> Void in
vc.view.frame = end
},
completion: nil)
}
I tried setting the view controller's background color to clear but still, it's not making the background transparent.
You should set the presentation style of the presented view controller to accordingly.
Set it to overFullScreen if you want it to display over the current window and to overCurrentContext if you just want to set it above the view controller's context.
Also, you should set definesPresentationContext to true.
vc.modalPresentationStyle = .overFullScreen
vc.definesPresentationContext = true
I have a popover view (without a tab bar) that is popped over to a view controller with a tab bar. In the view controller with a tab bar I set up a button to click, so that the view controller pops up:
#IBAction func PopUpClicked(_ sender: UIButton) -> Void {
let popOverVC = UIStoryboard(name: "SpinningWheel", bundle: nil).instantiateViewController(withIdentifier: "PhotoPopUp") as! PopUpViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParentViewController: self)
}
And in the popOver view controller, i animated the pop over.
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)
self.showAnimate()
// Do any additional setup after loading the view.
}
func showAnimate()
{
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
UIView.animate(withDuration: 0.25, animations: {
self.view.alpha = 1.0
self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
});
}
func removeAnimate()
{
UIView.animate(withDuration: 0.25, animations: {
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.view.removeFromSuperview()
}
});
}
But when the popover happens, Everything has a faded black background, which I want except for the tab bar. I would like for the pop over View to also pop over the tabbar and for the faded black background to go over it.
This is what I want it to look like:
With the black faded background covering the tabbar
This happens, because you have to present your popover as a modal ViewController. To achieve this you have to set the modal presentation style before presenting your popover from your target ViewController. This code should be called in your presenting ViewController:
let vc = YourPopOverViewController(nib: UINib(name: "PopOverViewController", bundle: nil), bundle: nil)
vc.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
tabBarController.present(vc, animated: true)
EDIT:
This should do the trick if you have designed your PopOverViewController as a fullscreen ViewController. I have done this a bunch of times and have left the space which should not be presented as clear background:
#IBAction func PopUpClicked(_ sender: UIButton) -> Void {
let popOverVC = UIStoryboard(name: "SpinningWheel", bundle: nil).instantiateViewController(withIdentifier: "PhotoPopUp") as! PopUpViewController
popOverVc.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
tabBarController.present(popOverVC, animated: true)
}
This 3rd party EzPopup can resolve the problem easily: https://github.com/huynguyencong/EzPopup
// init YourViewController
let contentVC = ...
// Init popup view controller with content is your content view controller
let popupVC = PopupViewController(contentController: contentVC, popupWidth: 100, popupHeight: 200)
// show it by call present(_ , animated:) method from a current UIViewController
present(popupVC, animated: true)