Adding Custom popup doesn't filling the full view iOS, Swift - ios

I have created a UIViewControlller and designed in storyboard, I want to show it as popup for my another view.
I used the following to show as popup:
guard let popupVC = UIStoryboard(name: "More", bundle: nil).instantiateViewController(withIdentifier: "LanguageSelectionViewController") as? LanguageSelectionViewController else{
fatalError("Unexpected destination VC")
}
self.addChildViewController(popupVC)
popupVC.view.frame = self.tableView.frame
print("POPUP Frame VIEW -- \(popupVC.view.frame)")
print("SElF VIEW -- \(self.tableView.frame)")
popupVC.view.frame = self.tableView.frame
print("POPUP Frame VIEW -- \(popupVC.view.frame)")
print("SElF VIEW -- \(self.view.frame)")
popupVC.modalPresentationStyle = .currentContext
popupVC.modalTransitionStyle = .crossDissolve
popupVC.view.bindFrameToSuperviewBounds()
self.view.addSubview(popupVC.view)
popupVC.didMove(toParentViewController: self)
It is working properly, but on my device half of the screen space is not filled by popup view.

Have you tried using the present() function? Something like this:
let popupVC = PopupViewController()
popupVC.modalPresentationStyle = .overFullScreen
popupVC.modalTransitionStyle = .crossDissolve
self.present(popupVC, animated: true, completion: nil)
I find designing view controllers in their own xib files easier, and it allows initialisation like in my example, rather than having to use the storyboard in code, but thats personal preference.
If it still isnt working, maybe check that the layout constraints for the popup's background are correct, so it actually fills it's parent.

You need to swap these two lines:
self.view.addSubview(popupVC.view)
popupVC.view.bindFrameToSuperviewBounds()
You can't bind a view to it's superview if the view hasn't been added to it yet.

First thing you need click on popup(storyboard or xib) and set it to background color .clear Color
Then make it to center. like
popupVC.center = self.view.center
it's just a guide you can change and set names accordingly. But my question why you are using storyboard why not have created Xib or View
Hope it will serve your purpose.

Related

add subview over UITableView

First of, I am noob to Swift programming.
I am trying to show a custom view over a UITableView.
I am facing two major issues :
a) The subview does not appear correctly firstly. ref image below :
and after few moments actual view is loaded :
b) After the UITableView is scrolled, the view is not coming over the current top scroll position of UITableView
Following is the code to add subview :
let vaAdPopupViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AdPopupWithCrossViewController") as! AdPopupWithCrossViewController
vaAdPopupViewController.adID = adID
vaAdPopupViewController.tableView = self.tableView
if let message = parseJSON["adv_text"] as? String{
vaAdPopupViewController.message = message
}
let navigationBarFrame: CGRect = (self.navigationController?.view.frame)!
let frameSize = CGRect(x: navigationBarFrame.minX, y: navigationBarFrame.minY, width: navigationBarFrame.width, height: (navigationBarFrame.height - (self.navigationController?.navigationBar.frame.size.height)!))
vaAdPopupViewController.view.frame = frameSize
self.tableView.addSubview(vaAdPopupViewController.view)
vaAdPopupViewController.view.tag = 1000
self.addChildViewController(vaAdPopupViewController)
vaAdPopupViewController.didMove(toParentViewController: self)
also in AdPopupWithCrossViewController :
override func viewDidLoad() {
self.view.superview?.layoutIfNeeded()
self.view.layoutIfNeeded()
super.viewDidLoad()
}
Please guide me how to resolve this issue.
Thank You.
You probably want to either create a Present Modally Segue or use present() via code.
You've already created your AdPopupWithCrossViewController. Set its background color to be translucent. Then you can present it like this:
let vaAdPopupViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AdPopupWithCrossViewController") as! ModalOverTableViewController
vaAdPopupViewController.modalPresentationStyle = .overCurrentContext
self.present(vaAdPopupViewController, animated: true, completion: nil)
Then, your little "X" button can remove the ad with:
#IBAction func closeTapped(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
You can try out the various options on .modalPresentationStyle and .modalTransitionStyle, as well as setting animated to true or false, to get the appearance / behavior you desire.
As Dan says, you should add your popup as a subview of the view controller's view, not of the table view. A Table view's view hierarchy is private and you should not be trying to mess with it.
Note that you can't do this with a table view controller. This has always bugged me, but it's a fact: A UITableViewController manages a single table view and nothing else. If you want a more complex view hierarchy you need to embed your table view controller in another view controller. I do this with a container view and an embed segue, which is very easy.
If you do that then you can add your new view controller's content to the parent view controller's content view, not to the table view controller's view (or to the table view itself)

Container View Page Controller is Being Clipped instead of Resized

I am about fifteen seconds away from flipping over my desk and rage quitting, because I just cannot figure this out.
I have a Page View Controller as the embed of a Container View Controller. Sounds easy, right?
Problem is, the Page View Controller is getting clipped. I need it to resize. So they would be cute little pages with their full VC content.
I've tried every option on the Storyboard Display... things.
Here's a couple of pics to describe the problem:
Now I would share the code with you, but all it is the loading of the (single) page. The page does exist in a different storyboard, but even when I changed the view for View Controllers in the Main storyboard, they were still being cut off.
override viewDidLoad() {
let storyboard = UIStoryboard(name: "TEMPLATES", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "template1")
self.setViewControllers([vc!], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
self.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] //Some code I found on Stack Overflow that did nothing
super.viewDidLoad()
}
Any help would be appreciated!
if you add it from the storyboard - it will just work.
if you add the child view controller from code - you also need to set the frame like so:
carsTableVC.view.frame = self.container.bounds
here is a full code example (carsTableVC is in a container):
let sb = UIStoryboard.init(name: "Cars", bundle: nil)
self.carsTableVC =
sb.instantiateViewController(withIdentifier:
"CarsTableViewController") as? CarsTableViewController
carsTableVC.view.frame = self.container.bounds
carsTableVC.willMove(toParent: self)
addChild(carsTableVC)
carsTableVC.didMove(toParent: self)
container.addSubview(carsTableVC.view)

showViewController method only displays modal views

Looking at Apples Resource for using showViewController() versus presentViewController() I can't seem to figure out my issue here.
I want to display a viewController from my storyboard programmatically by doing the following:
if let resultController = storyboard!.instantiateViewControllerWithIdentifier("mainTab") as? TabBarController {
showViewController(resultController, sender: UIBarButtonItem.self)
}
This works fine. However, it's presentation is always modal. Covering the screen vertically from bottom to top like so:
I was/still am under the impression that I should use showViewController to display a screen without the animation... But clearly I'm missing something here. All I want to do is display the VC non-modally. I feel like I've tried everything to no avail.
Thanks for the advice in advance.
I think you want to use something like this.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("Controller") as! UIViewController
self.presentViewController(vc, animated: false, completion: nil) // no animation or presentation as modal because animated is false
The key is to have animated set to false. This method works for me. Hope this helps!

How to present PopOver in iOS9

I am trying to create a pop over and when I present the view controller, the background is always solid black and the size is full screen.
I can't seem to figure out what's wrong and here is the code that I have
#IBAction func distancePopOver( sender : UIBarButtonItem){
//a UIViewController that I created in the storyboard
let controller = storyboard!.instantiateViewControllerWithIdentifier("distancePopOver")
controller.modalPresentationStyle= UIModalPresentationSTyle.PopOver
controller.preferredContentSize = CGSizeMake(200,30)
self.presentViewController(controller, animated: true, completion: nil)
//Configure the Popover presentation controller
let popController = (controller.popoverPresentationController)!
popController.permittedArrowDirections = UIPopoverArrowDirection.Down
popController.barButtonItem = sender
popController.delegate = self
}
Whenever I click on the UIBarButtonItem, it presents the view in full screen, but shouldn't it be the size I specify in line 5?
Popovers are quite finicky now. First, you are going to want to configure the popoverPresentationController before you present it.
Secondly, make sure your arrow direction is pointing the way the arrow points and not where the content is respective to the UIBarButtonItem. So, if its inside UIToolbar (and is near the bottom of the screen) you'll want .Down otherwise if its a navigation bar (near the top) you'll want to use .Up.
#IBAction func distancePopOver( sender : UIBarButtonItem){
//Configure the Popover presentation controller
let popController = (controller.popoverPresentationController)!
popController.permittedArrowDirections = .Down // .Up
popController.barButtonItem = sender
popController.delegate = self
//a UIViewController that I created in the storyboard
let controller = storyboard!.instantiateViewControllerWithIdentifier("distancePopOver")
controller.modalPresentationStyle = .Popover
controller.preferredContentSize = CGSizeMake(200,30)
presentViewController(controller, animated: true, completion: nil)
}
Now if you got this far and its still not working, its because the popover's default behavior in a compact size class is to fill the screen. Since you are already setting your view controller to be the popover's delegate you'll just need to implement this delegate function: adaptivePresentationStyleForPresentationController(_:traitCollection:) and return .None for the presentation style. This will allow you to even show a real looking popover on the iPhone. See my blog post: iPhone Popover for a full example of doing this.

iOS Swift Popup View Controller

I need to have a ViewController slide up, be centered, and overlay the current ViewController. I thought the following code would work but it does not:
let view = storyboard?.instantiateViewControllerWithIdentifier("castSpell") as! CastSpellViewController
view.modalPresentationStyle = .OverCurrentContext
presentViewController(view, animated: true, completion: nil)
The new ViewController is shown but just as a full screen view. I have it's size set to 400x300 in the storyboard. I know I can do the same thing by having a view within a view and then showing the overlay view. Is that the route I need to go?
You need to set the presentation style on the presenter, not the presenting view.
Use self.modalPresentationStyle = .OverCurrentContext
let popOverVC = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewControllerWithIdentifier("ViewControllerName") as! PopOverViewContoller
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.containerView.frame
self.containerView.addSubview(popOverVC.view)
popOverVC.didMoveToParentViewController(self)
Use the above code to add viewcontroller as a popover view. The container view is optional. I like using container views when the subviews position is fixed. I can position the container using autolayout and keep it hidden until needed.
In you case, you can place the container/subView at the bottom of the screen from where you need to slide up the subview.
UIView.animateWithDuration(0.5) { () -> Void in
//Animate here
}
Then change the frame of the container/subview inside the above block of code.
Note : Container view is just a normal UIView. I like naming it container :)

Resources