My UIViewcontroller is not filling the entire screen? - swift

I have a very simple app with two UIviewcontrollers. I want to dismiss one and present another one. However, when I do this (code below), the second viewcontroller does not fill the screen, instead it hovers over the top one and can easily get dismissed if you swipe from the top down (you can just about see the first viewcontroller at the top)?
VC-1:
#objc private func picksAction(){
print("picks button pressed")
let layout = UICollectionViewFlowLayout()
let viewController = GridPicksCollectionViewController(collectionViewLayout: layout)
let navController = UINavigationController()
navController.pushViewController(viewController, animated: true)
self.present(navController, animated: true) {}
}
Result:

Set modalPresentationStyle to .fullScreen:
navController.modalPresentationStyle = .fullScreen

Related

TabbarController not hiding when opening CameraController (BarCodeScanner)

I have a BarCodeScanner-viewController which I call from 3 different views. My app also has a tabbarController. Problem is, the tabbar hides from two of the viewControllers, while the third one always shows the tabbarController, while in cameraMode (barCodeScanner).
I've tried to set the ´self.tabBarController?.tabBar.isHidden = true´ in both viewDidLoad(), viewDidAppear() and viewWillAppear() and changed it to false on viewWillDisappear()
I have also tested to set 'scanner.hidesBottomBarWhenPushed = true' without result.
// working:
setUpBackButton(withTitle: NSLocalizedString("button_cancel", comment: ""))
let scanner = BarCodeScanner()
self.navigationController?.pushViewController(scanner, animated: true)
scanner.callback = { result in
// code with result
}
// working:
setUpBackButton()
let scanner = BarCodeScanner()
scanner.modalPresentationStyle = .overCurrentContext
self.navigationController?.pushViewController(scanner, animated: true)
scanner.callback = { result in
// code with result
}
// NOT WORKING (i.e. not hiding the tabbarController):
let scanner = BarCodeScanner()
setupBackButton()
scanner.modalPresentationStyle = .overCurrentContext
self.navigationController?.pushViewController(scanner, animated: true)
scanner.callback = { result in
// code with result
}
I wan't the tabbar to be hidden in the third example too.
Using Push actually adds a new controller in navigationController thats why your tabbar is not hiding to hide it with new controllers overlay you need to change push with present function in Thrid example
Replace
self.navigationController?.pushViewController(scanner, animated: true)
With
self.navigationController?.present(scanner, animated: true, completion: nil)

Present viewcontroller with tabbar

I created UITabBarController programmatically in AppDelegate with 4 view controllers(using .xib). When user tap some button on ViewController (VC-A) it present another VC (VC-B) and covered tabbar. So I want to VC-B has a tabbar on the button.
I tried to add VC-B as a child of tabbarcontroller. I tried to .present(vc) and .show(vc) on both: VC-A and VC-A.TabBarController
Creating controllers in AppDelegate:
let controllers = [tabViewController1,tabViewController2,tabViewController3,tabViewController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
presenting in VC-A
self.tabBarController?.present(controller, animated: false, completion: nil)
right click and drag from tabbar controller in storyboard to VC-B. that should create a tab on the bottom of your VC-A and VC-B to go back and forth without having to implement any backend code unless you want to animate
The solution is to embed every VC in navigationController and then add to TabBarController.
let vc1 = ViewController1()
let navController1 = UINavigationController(rootViewController: vc1)
navController.isNavigationBarHidden = true
let controllers = [navController1, navController2, navController3, navController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
Then call
self.navigationController?.pushViewController(controller, animated:
true)
To diplay VC with tabbar
I will press the red login button at the bottom of the picture and try to log in.
login button => "로그인"
After that, log in.
let moreVC = self.storyboard?.instantiateViewController(withIdentifier: "MoreViewController") as! MoreViewController
moreVC.definesPresentationContext = true
moreVC.modalPresentationStyle = .fullScreen
let navController = UINavigationController(rootViewController: moreVC)
self.present(navController, animated: true, completion: nil)
If the login proceeds without error, the above code will be called to display the screen when the login is completed.
If the flow proceeds as the code above, this screen appears.
The screen shown is not fullscreen, and the tabbar at the bottom is gone. The screen I want is the screen below.
How can I present a tab bar when presenting the screen?

Present below current view and not above

I'm trying to present a view controller below another presented view controller (like WhatsApp when you open camera and press gallery).
I tried many things but none worked ..
Use child view controller and set view of that added child view controller at the top of hierarchy. It will be top most element, so actual background of this view will be obscured, but that's the way to go.
//code inside UIViewController class
func addViewControllerAtBottom() {
let newVC = NewVCType() //just instantiate it
addChildViewController(newVC)
view.insertSubview(newVC.view, at: 0) //at 0 means it's first rendered, all others will be on top of it
}
You can reproduce this behavior by doing the following :
First, create a NavigationController with a root ViewController :
let navController = UINavigationController(rootViewController: firstController)
Then, present this navigationController with animated: false and in the completion of the present method, push your second ViewController, still with animated: false (to avoid weird animations) :
present(navController, animated: false) {
navController.pushViewController(secondController, animated: false)
}
Here you go, you got a new navigation with 2 UIViewController, like WhatsApp.
Full code, wrapped into a button's action :
#IBAction func buttonTapped(_ sender: Any) {
let navController = UINavigationController(rootViewController: firstController)
present(navController, animated: false) {
navController.pushViewController(secondController, animated: false)
}
}

Possible to create a UITableView that appears from the corner of a View Controller

I would like to model a table view after one found in the Todoist app (see below), is it possible to do this without and additional framework? If so how would I go about doing this?
You can create a view controller with a UITableView and present it as UIPopoverPresentationController
let vc = UIViewController()
vc.modalPresentationStyle = .popover
vc.preferredContentSize = CGSize(width: 200, height: 200)
let popUp = vc.popoverPresentationController
popUp?.permittedArrowDirections = .up
popUp?.delegate = self
popUp?.sourceView = sender as! UIView // here set the frame of the button that the arrow points to when popup is shown
present(vc, animated: true, completion: nil)
//
Inside the vc that you presents the popup make it implements the delegate UIPopoverPresentationControllerDelegate and write this method
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}

Attempt to present View Controller which is not in window hierarchy

My initial view controller is created from Storyboard. It has a button which adds a UINavigation :
let navigationController = UINavigationController(rootViewController: ListViewController)
self.presentViewController(navigationController, animated: true, completion:nil)
appDelegate.window?.rootViewController = navigationController
ListViewController has a UICollectionView. Tapping on cell (which I subclassed) calls a delegate method back to ListViewController and presents another View with UICollectionView:
let detailedListViewController = DetailedCollectionViewController(collectionViewLayout: UICollectionViewFlowLayout())
self.navigationController?.pushViewController(detailedListViewController, animated: true)
Inside this DetailedCollectionView each cell has a button to show a full-screen SFSafariViewController. So as before, using delegate I'm trying to show it like this:
SFSafariVC = SFSafariViewController(URL: urlToLoad)
SFSafariVC.view.frame = self.view.frame
self.presentViewController(SFSafariVC, animated: true, completion: nil)
By doing so, I can see the SFSafariView working correctly, but I get the message:
Warning: Attempt to present < UIAlertController: 0x7fcd96353e20 > on
< UINavigationController: 0x7fcd948a0600 > whose view is not in the
window hierarchy!
I tried changing self.presentViewController to self.navigationController?.presentViewController but still the same error persists..