Use toolbar to navigate properly - ios

I'm trying to do a instagram-like (or any app with a toolbar in fact) toolbar, to navigate from screens to screens.
I have a navigation controller, with 5 screens, and I already did this :
In each screen, in the viewDidLoad, I put:
self.toolbarItems = self.navigationController!.toolbarItems
And in the navigationController, for one BartbuttonItem I have this
function for example:
#IBAction func profileButtonClicked(sender: UIBarButtonItem) {
self.popToRootViewControllerAnimated(false)
self.performSegueWithIdentifier("showProfile", sender: self)
}
So it is working, but I don't like the transition when I go first to the navigationController then to the newViewController, I would like there is no transition at all.
I would be thankful if you help me.
Ben

Click the view Controller on main storyboard
Then go to attribute inspector
There is a option called transition style, choose cross dissolve
OR Use
self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController, animated: false, completion: nil)

FOUND :
just needed to uncheck "Animates", when you click on the segue in the storyBoard and then go to Attributes Inspector and just uncheck this checkbox.

Related

Why tab bar is missing after presenting a new view controller?

I have created a simple tab bar with three views in storyboard. The tab bar works well, but when I try to show another view controller from a button within a tab, the new view is placed over the whole screen and also over the tab bar.
This is how I present the view so far when a button is pressed:
#IBAction func buttonPressed(_ sender: UIButton) {
let newVC = self.storyboard?.instantiateViewController(withIdentifier: "extraVC")
self.present(newVC!, animated: true, completion: nil)
}
The other idea I had was this:
self.tabBarController?.present(vc!, animated: true, completion: nil)
But this didn't work either.
So how can I present another view controller within the tab bar (so that the bottom bar is still shown)?
When you present a view controller modally, its presentation style will be "Full Screen" by default. What you want to do is have it do in this case is just cover part of the screen (the part where the presenting view controller is drawn.
One way to accomplish this is to:
Set the modalPresentationStyle for the presented view controller to be .currentContext or .overCurrentContext
In the view controller that will be presenting the modal, set its definesContext property to true.
These steps can be done either in Interface Builder by setting attributes on the segue and the view controller, or you can modify your code to include the following:
#IBAction func buttonPressed(_ sender: UIButton) {
let newVC = self.storyboard?.instantiateViewController(withIdentifier: "extraVC")
self.definesPresentationContext = true
newVC?.modalPresentationStyle = .overCurrentContext
self.present(newVC!, animated: true, completion: nil)
}
What this combination of properties does is:
Indicate for the presented view controller that you want it to be presented in a non-full screen context (some specific section of the screen)
Indicate that the presenting view controller is in the section of the screen / the context you want the modal to be drawn according to.
More details can be found in the Apple Documentation
When you are using present method, the ViewController is presented modally and covers your UITabBarConntroller. Instead of showing your view modally you can embed every first view controller in your TabBar into UINavigationController and then use method pushViewController to push it onto stack. You will have your TabBar visible and nice looking animation for free.
In Xcode, I created a new project using the Tabbed App template to illustrate the solution above. This will create a project with a tabbar controller and two view controllers. I added a button with the title "view page" to the first view controller and embedded a navigation controller from the storyboard.
The storyboard will look like this after making the above changes:
In the FirstViewController.swift file, I created an IBAction for the button with the following code that will create another view controller called DetailViewController, with the title Favorites and a background color of orange. I used the navigation controller to present it by pushing it onto the navigation controller stack.
#IBAction func viewPageButtonTapped(_ sender: UIButton) {
print("viewPageButtonTapped")
let pinkViewController = DetailViewController()
pinkViewController.title = "Favorites"
pinkViewController.view.backgroundColor = UIColor.orange
navigationController?.pushViewController(pinkViewController, animated: true)
}
When I run the project on the simulator, I got the desired result. Hope this helps give you some ideas.
In your viewController do:
self.tabBarController?.present(nextViewController, animated: true/false, completion: {})

dismiss two controllers Swift

I have this situation :
I have a first view controller , when tap on button in it I open in modal mode another view controller , in this view controller when I tap another button I open in modal view another view controller and in it there is a button and when I tap on it I want to go to first view controller without re-initialize it.
How do I do it?
This is the perfect situation for an unwind segue.
Put this in your first viewController (the one you want to return to):
#IBAction func backFromVC3(_ segue: UIStoryboardSegue) {
print("We are back in VC1!")
}
Then in the Storyboard in your 3rd viewController, control-drag from your button to the exit icon at the top of the viewController and choose backFromVC3 from the pop-up.
Now, when the user presses the button in VC3, both VC3 and VC2 will be dismissed and you will return to VC1.
If you are not using Storyboards, you can dismiss the viewControllers with code. Here is code for a button's handler to dismiss two levels of viewController:
func doDismiss(_ sender: UIButton) {
// Use presentingViewController twice to go back two levels and call
// dismissViewController to dismiss both viewControllers.
self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}
Thanks all for reply and edited my question :)
I found 2 line code to resolved my problem:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window!.rootViewController?.dismissViewControllerAnimated(true, completion: nil).
And that work well.
Thanks very much

Segues from a PopupView

I am facing a problem I cannot solve alone. At least, I don't know what's the right way to program this. I am writing an app which will open a PopupView as a Subview of my main menu when pressing + . This looks like this:
As soon as this subview is visible, I want to perform different segues (when pressing button 1,2,3 or 4) so this popup can change the view to 1-4:
I created a separate Storyboard for this popup and when pressing +, the initial view of it will be added as a subview:
let addFilePopup : UIStoryboard = UIStoryboard(name: "AddFilePopup", bundle: nil)
animations.showInView(self.view, aView: addFilePopup.instantiateInitialViewController()?.view, animated: true)
// the method for adding the PopupView as a Subview
func showInView(superView: UIView, aView: UIView!, animated: Bool)
{
aView.center = superView.center
superView.addSubview(aView)
if animated
{
self.showAnimate(aView)
}
}
Showing the Popup itself works so far, but as soon as I press one button, the segue of the Popup is not performed... Do you have any hints to me for this problem? Besides, is this the right approach?
If you also could let me know how I can make the superview.alpha = 0,5 and ignoring touches without taking affect on the subview that would be great too. Thanks in advance!

Programmatically changing View Controllers without Navigation Controller Swift

I want to switch to a new view controller when I press a button without using a navigation controller and I can't seem to be able to do this. I have looked everywhere for an answer but everything that I have found is either in objective-c, using a navigation controller, or not working at all.
func gunsoutButtonPressed(sender:UIButton!) {
print("yay\t")
//let encounterVC:AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier("ecounterViewController")
//self.showViewController(encounterVC as UIViewController, sender: encounterVC)
let encounterViewController = self.storyboard.instantiateViewControllerWithIdentifier("encounterViewController") as encounterViewController
self.pushViewController(encounterViewController, animated: true)
}
You have to connect the two ViewControllers you would like to use. Then name the segue however you want and then use the following code to trigger the segue (inside an IBAction or something). It is not completely programmatically but you can trigger them programmatically, which should be enough.
performSegueWithIdentifier("mySegue", sender: nil)
Check out this video for support.
Hope this helps :)
You cannot use a push segue without a UINavigationController. You could achieve this with a modal segue, such as this:
self.presentViewController(encounterViewController, animated: true, completion: nil)
Segue
So you use the Segue ID to make sure you segue correctly.
No Segue
I would suggest doing this instead though:
let vc = ViewControllerToSegueTo()
self.presentViewController(vc, animated: true, completion: nil)
It is slightly better if you do not want to use the storyboard.

Swift: miss tab bar after click Back button

I'm new to swift and IOS development. I'm working on a tabbed application(3 views). For example, FirstView, SecondView and ThirdView. FirstView has a button that opens a addNewSession view and the addNewSession view has a Back button that back to the FirstView. The problem is Tab bar disappears after back from the addNewSession view
FirstView to addNewSession view.
#IBAction func toAddNew(sender: AnyObject) {
let addNewSession = self.storyboard?.instantiateViewControllerWithIdentifier("addNewSession") as addNew
self.presentViewController(addNewSession, animated: true, completion: nil)
}
addNewSession view to FirstView
#IBAction func backToPrev(sender: AnyObject) {
println("test1")
let FirstView = self.storyboard?.instantiateViewControllerWithIdentifier("FirstView") as FirstViewController
self.presentViewController(FirstView, animated: true, completion: nil)
}
The problem is your backToPrev method is instantiating a new FirstViewController, which is not the same instance you came from. You are not really going back to the original one, you are showing a new one. This is not what you want.
The proper way to do this is to embed the FirstViewController in a navigation controller, then push the addNew controller onto it. When you use a nav controller, you get the Back behavior for free.
Hopefully you are using a storyboard? Select your FirstViewController, go to the Editor menu and choose Embed in Navigation Controller.
In your toAddNew, instead of presentViewController use self.navigationController.pushViewController to push your addNew controller.
There's an even easier way to do this last step, using segues. You control drag in the storyboard from your button in FirstViewController to the addNew controller and create a Show segue. This will automatically show your addNew controller when the button is touched. With this approach, you will want to remove your toAddNew IBAction and the connection since it's redundant.

Resources