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.
Related
I have this kind of flow page :
Setting Page --> Enter Password --> Go to Page X
So in setting page, in order to go to page X, I have to enter a password using pop up view.
When I'm in page X and i want to go back to previous page, I go to enter password pop up view, instead of the setting page.
How do I skip that page?
My pop up view code is something like this :
let btn = storyboard?.instantiateViewController(withIdentifier: "PopUpView") as! PopUpView
addChild(btn)
btn.view.frame = view.frame
view.addSubview(btn.view)
btn.didMove(toParent: self)
I'm fairly new here, any help will be appreciated.
Thankyou.
use the settings view controller's present function to open the popup.
//In your settings view
func openPopup() {
let btn = storyboard?.instantiateViewController(withIdentifier: "PopUpView") as! PopUpView
self.present(btn, animated: true, completion: nil)
}
When the user clicks ok, call dismiss on your popup view and use the closure to initiate the page opening to X
//In your 'PopUpView' On the OK button action of your popup
func didTouchOk() {
self.dismiss(animated: true) { [weak self] in
guard let self = self else { return }
//Put your open page X code here
let XView = storyboard?.instantiateViewController(withIdentifier: "XViewController") as! XView
self.present(XView, animated: true, completion: nil)
}
}
if you are using navigationController:
Declare a protocol in your PopUpView
protocol popupDelegate: class {
func userDidTouchOkInPopup()
}
create a weak var in your PopUpView
weak var delegate: popupDelegate? = nil
In your settings viewcontroller:
Assign delegate to popup before pushing
func openPopup() {
let btn = storyboard?.instantiateViewController(withIdentifier:
"PopUpView") as! PopUpView
btn.delegate = self
self.navigationController?.pushViewController(btn, animated: true)
}
Implement an extension for this protocol
extension SettingsViewController: popupDelegate {
func userDidTouchOkInPopup() {
self.navigationController?.popViewController(animated: true)
let XView = storyboard?.instantiateViewController(withIdentifier:
"XViewController") as! XView
self.navigationController?.pushViewController(XView, animated: true)
}
}
Modify the Ok action in your PopUpView
//In your 'PopUpView' On the OK button action of your popup
func didTouchOk() {
self.delegate?.userDidTouchOkInPopup()
}
If you are in navigationController hierarchy, use navigationController.popToViewController to go to the specific ViewController.
In ViewDidLoad, hide the present backButton and create a new One and associate action with it.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(backButtonFunction))
self.navigationItem.leftBarButtonItem = newBackButton
}
Inside backButtonFunction, you can put the code
#objc func backButtonFunction(){
if let navController = self.navigationController {
for controller in navController.viewControllers {
if controller is SettingsViewController { // Change name of ViewController accordingly
navController.popToViewController(controller, animated:true)
break
}
}
}
}
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)
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()
}
I've created a CustomTabBarController class with 5 buttons that work perfectly fine.
Each button triggers an individual view controller.
Example: home button triggers the homeViewController and shows it on the screen perfectly.
In the homeViewController, I've created a right bar button item with the following code:
let homeButton = UIBarButtonItem(image: UIImage(named: "HomeButton"), style: .plain, target: self, action:#selector(homeViewController.goToHomeVC)
self.navigationItem.rightBarButtonItem = homeButton
func goToHomeVC(sender: UIButton) {
// Go to home page (tab bar index 0)
}
How can I implement my tappedHome function so it can access the tab bar item (Home) so it triggers the homeViewController and shows it on the screen?
Basically, That is not actual UITabBarController so, You have to maintain the push and pop manually.
Here the code of push and pop that will help you to move between your five view-controller classes.
func pushIfRequired(className:AnyClass) {
if (UIViewController.self != className) {
print("Your pushed class must be child of UIViewController")
return
}
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var isPopDone = false
let mainNavigation = UIApplication.shared.delegate?.window??.rootViewController as? UINavigationController
let viewControllers = mainNavigation!.viewControllers
for vc in viewControllers {
if (type(of: vc) == className) {
mainNavigation?.popToViewController(vc, animated: true)
isPopDone = true
break
}
}
if isPopDone == false{
let instanceSignUp = storyboard.instantiateViewController(withIdentifier: NSStringFromClass(className)) // Identifier must be same name as class
mainNavigation?.pushViewController(instanceSignUp, animated: true)
}
}
Uses
pushIfRequired(className: FirstTabVC.self)
If you don't mind checking the parent to get to your CustomTabBarController,
func navButtonPressedAction() {
guard let tabVC = self.parent?.parent as? UITabBarController else { return }
tabVC.selectedIndex = 2 //Index of the tab bar item here
}
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"
}