After i set my initial ViewController manually in the AppDelegate.swift
my UISwipeGestureRecognizer is not working.
This is how my AppDelegate look like:
self.mainNavigationController = UINavigationController()
var mainController: UIViewController? = TineLineViewController()
self.mainNavigationController!.pushViewController(mainController!, animated: true)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.rootViewController = mainController
self.window!.makeKeyAndVisible()
and this is how my UISwipeGestureRecognizer is set in the initial ViewController:
let postLeft : Selector = "postLeft:"
let postLeftSwipe = UISwipeGestureRecognizer(target: self, action: postLeft)
postLeftSwipe.direction = UISwipeGestureRecognizerDirection.Left
goToPostButton.addGestureRecognizer(postLeftSwipe)
And this is my postLeft method which instantiate a new ViewController and navigate to it.
func postLeft(sender: AnyObject) {
println("left swipe to push...")
let secondViewController = PostCreateController()
self.presentViewController(secondViewController, animated: true, completion: nil)
}
When I swipe, the postLeft method was called, I can see the println left swipe to push, but the application doesn't changed the view.
Does anybody have any solution to solve this issue?
Thank you!
UPDATE:
i change my postLeft method. and by the console i see my new viewController class instantiates but it's not showing up.
I think you don't set your navigationController correctly,
try this instead of self.navigationController!.pushViewController
let secondViewController = PostCreateController()
self.presentViewController(secondViewController, animated: true, completion: nil)
Related
I have a main tabBarController and would like to present a viewController modally when a certain tabBarItem is tapped.
I am loading the viewControllers in my tabBarController as...
func setupViewControllers() {
self.tabBar.isHidden = false
if let firstVC = storyboard?.instantiateViewController(withIdentifier: "first") as? FirstViewController, let secondVC = storyboard?.instantiateViewController(withIdentifier: "second") as? SecondViewController, let thirdVC = storyboard?.instantiateViewController(withIdentifier: "third") as? ThirdViewController, let fourthVC = storyboard?.instantiateViewController(withIdentifier: "fourth") as? FourthViewController, let fifthVC = storyboard?.instantiateViewController(withIdentifier: "fifth") as? FifthViewController {
let firstNavController = UINavigationController(rootViewController: firstVC)
let secondNavController = UINavigationController(rootViewController: secondVC)
let fourthNavController = UINavigationController(rootViewController: fourthVC)
let fifthNavController = UINavigationController(rootViewController: fifthVC)
firstNavController.tabBarItem.image = image
secondNavController.tabBarItem.image = image
fourthNavController.tabBarItem.image = image
fifthNavController.tabBarItem.image = image
thirdVC.tabBarItem.image = image
tabBar.tintColor = nil
//Load tabBar viewControllers
viewControllers = [homeNavController, postNavController, plusMenuVC, meetupNavController, profileNavController]
}
}
I then conformed the tabBarViewController to the UITabBarControllerDelegate to invoke the method...
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if tabBarController.selectedIndex == 2, let thirdVC = viewController as? ThirdViewController {
thirdVC.modalPresentationStyle = .overFullScreen
thirdVC.modalTransitionStyle = .crossDissolve
present(thirdVC, animated: true, completion: nil)
return false
} else { return true }
}
The above however never gets triggered. I tried setting in viewDidLoad
self.delegate = self
I tried setting the root navigation controllers and its ancestor tabBarController delegate to self.
Nothing seemed to work and I hope someone can guide me as I've been unable to debug and find an existing solution...
UPDATE
So I created a dummyThirdVC to replace the thirdVC in the setupViewControllers() function. In the dummyThirdVC, I conformed to UITabBarControllerDelegate and in viewDidLoad I set the self.tabBarController.delegate = self. Then I took the delegate method and entered it into this dummyThirdVC, where inside this delegate method, I instantiated the real thirdVC to present.
The delegate method finally triggers properly, but my issue now is, the dummyThirdVC and its view must first load and appear for the delegate to be set and triggered thereafter.
How can I not show the dummyThirdVC and immediately just present the instantiated, real thirdVC? I had tried dummyThirdVC.viewDidLoad() in my setupViewControllers function to no avail...
I believe your check is wrong. You're checking for selectedIndex to be 2, but the selectedIndex 's value will always be the actual tab bar's selected index, and not the index that is going to be selected, so you're basically never going to reach selectedIndex as 2.
You also cannot present a view controller that is already active, and thirdVC is already active in your tabBar, thus you will get an error. A workaround for this is to use a viewController as placeholder for image and title in the tab bar and instantiate another one for presenting.
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController is ThirdViewController {
let vcToPresent = storyboard?.instantiateViewController(withIdentifier: "third") as? ThirdViewController
vcToPresent.modalPresentationStyle = .overFullScreen
vcToPresent.modalTransitionStyle = .crossDissolve
present(vcToPresent, animated: true, completion: nil)
return false
}
return true
}
I am trying to present a view that is showd from the bottom to the top. This is my code
let myPageViewController = storyboard?.instantiateViewController(withIdentifier: "myPageViewControllerID") as! MyPageViewController
myPageViewController.modalPresentationStyle = .fullScreen
let navController = UINavigationController(rootViewController: myPageViewController)
navigationController?.present(navController, animated: true, completion: nil)
Despite I am using .fullScreen, the view is not presented on full screen.
I tried using peformSegue to show the view with this code
self.performSegue(withIdentifier: "myPageViewSegue", sender: nil)
the page is presented on fullscreen but from the left to the right and not from the bottom to the top.
The third code I tried is this one
let detailVC = MyPageViewController()
let navigationController = UINavigationController(rootViewController: detailVC)
navigationController.modalPresentationStyle = .fullScreen
present(detailVC, animated: true)
here I get an error Application tried to present modally an active controller. I tried to add self.dismiss when disappearing MyPageViewController but it didn't helped.
The problem maybe is you are not presenting navigationController you are presenting detail vc, Use this
'let detailVC = MyPageViewController()
let navigationController = UINavigationController(rootViewController: detailVC)
navigationController.modalPresentationStyle = .fullScreen
present(navigationController, animated: true)'
if problem still exists use
navigationController.modalPresentationStyle = .overCurrentContext
Try this one:
let detailVC = MyPageViewController()
detailVC.modalPresentationStyle = .fullScreen
present(detailVC, animated: true)
You could try this, worked for me:
Setup up your segue:
performSegue(withIdentifier: "myPageViewSegue", sender: self)
Then use the prepare for segue method:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destVC = segue.destination as! MyPageViewSegue
destVC.modalPresentationStyle = .fullScreen
}
I ran into this problem and was stumped. Then I realized that overriding dismiss also overrides .fullscreen
// This breaks .fullscreen
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
super.dismiss(animated: flag, completion: completion)
// do something
}
It's clear that you don't need this if .fullscreen is being used, but leaving it in place caused problems.
You need to change your code with below lines and then Booom work like a charm
let vc = MyPageViewController()
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true)
let detailVC = MyPageViewController()
let navigationController = UINavigationController(rootViewController: detailVC)
navigationController.modalPresentationStyle = .overCurrentContext
present(detailVC, animated: true, completion: nil)
Explanation:
Its very simple. Its better to explain it line by line. Line 1: Declare the viewcontroller. Line 2: Add Navigation Controller (its optional. If you don't need, then you may skip navigation bar). Line 3: We have defined the modal presentation style link as overCurrentContext. and present the navigationController (it will come up with navigation bar and viewcontroller) or only the viewcontroller as per your need. In this piece of code, you will get the viewcontroller without navigation bar.
How do you change the view controller when a button is clicked. I am not using the Storyboard. The views were all created programmatically.
I tried adding a target to the button and then calling the following method to push the new View Controller:
func switchView() {
print(123)
let prodListController = ProductListController()
self.navigationController?.pushViewController(prodListController, animated: true)
}
This was called from within the UIviewController class.
Any help will be greatly appreciated. Thanks!!
EDIT:
Made the following modifications:
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: ProductListController())
Are you using navigationController? It looks like it is "nil"...
You can do it with "show" instead:
self.show(ProductListController(), sender: self)
However, if you want to use navigationController, you have to set it up first.
For example (supposing you will start your app with a navigationController):
on didFinishLaunchingWithOptions (AppDelegate.swift):
// Override point for customization after application launch.
self.window = UIWindow(frame: UIScreen.main.bounds)
let initialViewController = NavViewController()
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
on viewDidLoad of NavViewController.swift:
self.pushViewController(ViewController(), animated: true)
and then, you can use your code for the button:
func switchView() {
print(123)
let prodListController = ProductListController()
self.navigationController?.pushViewController(prodListController, animated: true)
}
You can try this code to push another viewcontroller
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var navVC = UINavigationController()
var yourVC = YourViewController()
navVC.viewControllers = [yourVC]
self.window!.rootViewController = navVC
self.window?.makeKeyAndVisible()
hope this will resolve your problem.
I have a question regarding blureffects on a view controller. I program all of my segues manually for several reasons. But when I go to a viewcontroller that has a blureffect background, I only see a dark gray background. How can I solve this that the view controller blur effect lays on top of another viewcontroller where the content of the previous viewcontroller can be seen through?
The blureffects are now applied by storyboard with transparant background views.
My code for seque is:
Action:
#IBAction func ToUserSections(_ sender: Any) {
let controller =
Navigation.getDestinationViewControllerWith("User",
controllerName: "UserSectionsVC")
present(controller, animated: false, completion: nil)
}
Class:
class Navigation{
static func getDestinationViewControllerWith(_
storyboardName:String, controllerName:String)-> UIViewController{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller =
storyboard.instantiateViewController(withIdentifier:
controllerName) as UIViewController
return controller
}
}
Hope you can help me with this because it will maximize aesthetics for the app :D
try this.
let viewController : CustomViewControlller = UIStoryboard.getMainStoryboard().instantiateViewController(withIdentifier: "Identifier") as! CustomViewControlller
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
self.present(viewController, animated: true, completion: { _ in })
Alright for others to know, what worked for me was the following:
At IBAction: adding the following line before presenting
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
Like this:
#IBAction func ToUserSections(_ sender: Any) {
let controller = Navigation.getDestinationViewControllerWith("User", controllerName: "UserSectionsVC")
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
present(controller, animated: false, completion: nil)
}
I'm looking for changing my ViewController from a gameScene with SpriteKit.
I have 3 scenes with 3 different ViewControllers.
When my application starts with the PresentationViewController (see the screenshot 1) my transition code from my GameScene (GameViewController) to the GameOverViewController doesn't work and I can read an error message.
error message :
whose view is not in the window hierarchy!
My code is :
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let settingController: UIViewController = storyboard.instantiateViewControllerWithIdentifier("PresentationViewController") as UIViewController
let vc = self.view?.window?.rootViewController
vc?.presentViewController(settingController, animated: true, completion: nil)
And when my app starts with the GameViewController (see the screenshot 2) the transition code works perfectly.
I don't know why is there a difference between this 2 cases.
For information the transition between PresentationViewController and GameViewController is with a UIButton with this code :
override func viewDidLoad() {
super.viewDidLoad()
var playButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
let image = UIImage(named: "playButton.png") as UIImage
playButton.frame = CGRectMake(0, 0, 100, 100)
playButton.center = CGPointMake(self.view.frame.width/2, self.view.frame.height/1.7)
playButton.addTarget(self, action: "transition:", forControlEvents: UIControlEvents.TouchUpInside)
playButton.setBackgroundImage(image, forState: UIControlState.Normal)
self.view.addSubview(playButton)
}
func transition(sender:UIButton!)
{
println("transition")
let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("GameViewController") as UIViewController
secondViewController.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.presentViewController(secondViewController, animated: true, completion: nil)
}
Well I found by myself a way to navigate between several ViewController.
I set the secondViewController to be the rootViewController in replace this code in my PresentationViewController file func transition():
self.presentViewController(secondViewController, animated: true, completion: nil)`
by this code (with options) :
secondViewController.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
let window = UIApplication.sharedApplication().windows[0] as UIWindow
UIView.transitionFromView(
window.rootViewController!.view,
toView: secondViewController.view,
duration: 0.65,
options: .TransitionCrossDissolve,
completion: {
finished in window.rootViewController = secondViewController
})