UIBarButtonItem depending on presentation. Swift3 - ios

I am facing a problem, because there are two ways how do I display my ViewController.
First way is performSegue(withIdentifier: "segue", sender: self)
It works fine because then I have this back button in my navigationItem:
Then I use this code to present the same ViewController (from another viewController than in the first case):
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navVC = storyboard.instantiateViewController(withIdentifier: "navViewController") as! UINavigationController
let vc = navVC.topViewController as! ViewController
self.present(navVC, animated: true, completion: nil)
but then I do not have any back button in my ViewController.
My question is: How can I keep my backButton (exactly how it is) when I use this function: performSegue(withIdentifier: "segue", sender: self) , but add button (can look different) when I use this function: self.present(navVC, animated: true, completion: nil)
Note: In my case 1 my segue is connected right to ViewController , but in case 2 I present UINavigationController and ViewController is embed in in this UINavigationController.
Edit: I tried this code, but it always prints: "1.........":
if self.presentingViewController != nil {
print("1..........")
} else if self.navigationController?.presentingViewController?.presentedViewController == self.navigationController {
return print("2.........")
} else if self.tabBarController?.presentingViewController is UITabBarController {
return print("3........")
}
And also this code prints:"Else.............." :
let isPresentingInAddMealMode = presentedViewController is UINavigationController
if isPresentingInAddMealMode {
print("FirstOption......................")
} else {
print("Else......................")
}
If you need more info just let me know.
Thank you very much.

you need to check presentedViewController and add back button as below .
if ([self presentedViewController]) {
// add your back button item here
}

Try this:
let viewController = storyboard?.instantiateViewController(withIdentifier: "Login") as! LoginView
let customNavigation = UINavigationController(rootViewController: viewController)
customNavigation.navigationBar.tintColor = UIColor.black
self.present(customNavigation, animated: true, completion: nil)
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Login"
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: self, action: #selector(self.backButton))
}
func backButton() {
self.dismiss(animated: true, completion: nil)
}
Try to set Image in UIBarButtonItem

I have solved it!! I put restorationIdentifier to my root navigationController and then I just check if that is navigationController with my restorationIdentifier like this:
if self.navigationController?.restorationIdentifier == "navViewController"{
let leftItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(goBack))
self.navigationItem.leftBarButtonItem = leftItem //Adds item if id is navViewController
}else{
self.navigationItem.leftBarButtonItem = nil //removes it and keeps "<Back"
}

Related

Custom tabbar button action is not working as expected

having some item at tabBar. Created a custom button for "Offers" and want to perform function on this, like navigation to other controller.
btnOffers.addTarget(self, action: #selector(buttonAction(sender:)), for: .touchUpInside)
In buttonAction my code is
#objc func buttonAction(sender: UIButton) {
if AppConstants.arrNames.count > 0 {
self.lblOfferBadge.isHidden = true
let storyboard = UIStoryboard(name: RMConstant.Dashboard, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "SentItemController") as! SentItemController
controller.transitioningDelegate = self
controller.modalPresentationStyle = .custom
controller.arrOffers = AppConstants.arrBestOffers
AppConstants.APP_DEL.rootviw.pushViewController(controller, animated: true)
} else {
// simple alert message
}
}
Currently pushing the SentItemController, but want to show SentItemController with tabBar visible via touch on "Offers" Button.

How can I switch programmatically between view controllers that are not on the same storyboard?

I am trying to switch between a view controller (that is coded programmatically) to a ViewController with the UI Elements on the storyboard.
I am trying to switch between a HomeController to a TabBarController using a button but by pressing the button it switches to a dark screen. I would be glad if some of you could help me out.
Here is my code:
var welcomeLabel: UIButton = {
let label = UIButton()
label.tintColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.alpha = 0
label.addTarget(self, action: #selector(handleLogin), for: .touchUpInside)
return label
}()
...............
#objc func handleLogin() {
navigationController?.show(TabBarController(), sender: Any?.self)
}
use this code if you're pushing view from NavigationController
navigationController?.pushViewController("YourViewController", animated: true)
You can do it in following way
let storyboard = UIStoryboard(name: "Your_storyboard", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "Your_View_controller") as! Your_View_controller
Now to present
self.present(viewController, animated: true, completion: nil)
Or through navigation controller
navigationController?.pushViewController(viewController, animated: true)
You can try this -
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) // Give the name .e.g if you have the different story board name
let YourNextViewController = storyBoard.instantiateViewController(withIdentifier: "your story board identifier") as! StoryBoardName/ClassName
self.navigationController?.pushViewController(YourNextViewController, animated: true)
//Or if you want to present viewController
self.present(YourNextViewController, animated:true, completion:nil)

Show BlurEffect on manual segue

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)
}

Changing UIButton of a ViewController from another ViewController in swift 3

I have two ViewController say A, B and C A contains arrays of UIBUtton and a function. The function uses a tag to identify the button pressed, There is a button (the red x button) that displays B ontop of A with a menu, when the menu (i.e B) is clicked it removes controller B before navigating / push to view controller C. This works well.
The red button in controller A rotates from "x" to "+" when clicked. If its "+" the controller B is displayed if "x" its removed. The problem is when am on C and I go back the button still remains as "+" instead of "x" the default state.. I have tried a lot solution from SO using delegate but none tend to solve my problem. Below are the screenshot and code have worked on so far
View Controller A
#IBAction func didPressTab(_ sender: UIButton) {
if (sender.tag != 2) {
let previousIndex = selectedIndex
selectedIndex = sender.tag
buttons[previousIndex].isSelected = false
let previousVC = contentViewControlers[previousIndex]
previousVC.willMove(toParentViewController: nil)
previousVC.view.removeFromSuperview()
previousVC.removeFromParentViewController()
sender.isSelected = true
let vc = contentViewControlers[selectedIndex]
addChildViewController(vc)
vc.view.frame = contentView.bounds
contentView.addSubview(vc.view)
vc.didMove(toParentViewController: self)
buttons[2].setImage(#imageLiteral(resourceName: "cancel"), for: .normal)
toogle = false
} else {
selectedIndex = sender.tag
//buttons[selectedIndex].isSelected = false
if (!toogle) {
buttons[selectedIndex].setImage(#imageLiteral(resourceName: "add"), for: .normal)
buttons[selectedIndex].isSelected = true
let vc = contentViewControlers[selectedIndex]
addChildViewController(vc)
vc.view.frame = contentView.bounds
contentView.addSubview(vc.view)
vc.didMove(toParentViewController: self)
toogle = true
} else {
buttons[selectedIndex].setImage(#imageLiteral(resourceName: "cancel"), for: .normal)
let previousVC = contentViewControlers[selectedIndex]
previousVC.willMove(toParentViewController: nil)
previousVC.view.removeFromSuperview()
previousVC.removeFromParentViewController()
toogle = false
}
}
}
func normalizeView() {
buttons[2].setImage(#imageLiteral(resourceName: "cancel"), for: .normal)
toogle = false
}
ViewController B (When the menu is clicked)
#IBAction func menuClicked(_ sender: UIButton) {
if (sender.tag == 0) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let CViewController = storyBoard.instantiateViewController(withIdentifier: "pass_code") as! CViewController
present(CViewController, animated: true, completion: nil)
} else if (sender.tag == 1) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let profileViewController = storyBoard.instantiateViewController(withIdentifier: "profile") as! ProfileViewController
present(profileViewController, animated: true, completion: nil)
}
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let AViewControler = storyBoard.instantiateViewController(withIdentifier: "dashboard") as! AViewController
//This is the code that tries to change the button from "+" back to default "x" but trows an error that an optional value is nil
AViewControler.normalizeView()
//This removes A from the view
willMove(toParentViewController: nil)
self.view.removeFromSuperview()
removeFromParentViewController()
}

PopoverPresentationController coming as nil

Created a SingleViewApplication in that I have placed a button.
Now clicking on button I need to display a tableView as popover.
The TableViewController is created in xib.
The issue is tableViewController.popoverPresentationController always comes as nil see below code
let filterVC = TableViewController(nibName: "TableViewController", bundle: nil)
var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
filterDistanceViewController.preferredContentSize = CGSize(width: 300, height: 200)
let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .any
if let pop = filterDistanceViewController.popoverPresentationController {
pop.delegate = self
}
in above code
filterDistanceViewController.popoverPresentationController is always coming as nil
Any hint in right direction will be highly appreciated.
Until you've set a modalPresentationStyle on your VC, the popoverPresentationController property will be nil. Ensure that you set the modalPresentationStyle before accessing.
You are not presenting anything, so you need to present the popoverPresentationViewController on the current viewcontroller, for example:
#IBAction func importantButtonPressed(_ sender: UIButton) {
let tableViewController = UITableViewController()
tableViewController.modalPresentationStyle = .popover
present(tableViewController, animated: true, completion: nil)
if let pop = tableViewController.popoverPresentationController {
pop.delegate = self
}
}
You may do like below.
#IBAction func popoverBtnPressed(_ sender: Any) {
let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController2")
vc2.modalPresentationStyle = .popover
vc2.popoverPresentationController?.delegate = self
vc2.popoverPresentationController?.barButtonItem = popoverBtn
vc2.popoverPresentationController?.sourceRect = .zero
present(vc2, animated: true, completion: nil)
}

Resources