perform segue with the same button to two different viewControllers based on information in uitextfield - swift

I am trying to make my view controller segue to two different view controllers with the same button. But i want the segue's to be done based on information that is in an uitextfield. e.g = if the textfield contains the right information then i will need the segue to perform to segue to viewControllerA if the information does not match my array of strings, ViewController will segue to viewControllerB.
Sample code:
#IBOutlet var pcTextField: UITextField!
#IBOutlet var odButton: UIButton!
var activePcText = ["over", "left", "weak", "never"]
override func viewDidLoad() {
super.viewDidLoad()
pcTextField.delegate = self
let tapRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard")
view.addGestureRecognizer(tapRecognizer)
odButton.hidden = true
self.pcTextField.addTarget(self, action: "pcEmpty", forControlEvents: UIControlEvents.EditingChanged)
}
#IBAction func odButton(sender: AnyObject) { }
I tried to implement an if statement as..
#IBAction func odButton(sender: AnyObject) {
if pcTextField.text!.containsString(activePcText) { }
}
I just get an error saying:
Cannot convert value of type '[String]' to expected argument type 'String'

#IBOutlet weak var pcTextField: UITextField!
let activePcText = ["over", "left", "weak", "never"]
#IBAction func buttonPressed(sender: UIButton) {
let text = pcTextField.text?.lowercaseString ?? ""
let destination = activePcText.map { $0.lowercaseString }.contains(text) ? "viewControllerA" : "viewControllerB"
performSegueWithIdentifier(destination, sender: self)
}
This makes it case insensitive.

This is an example of a prepareForSegue method that would accomplish what it sounds like you want to do
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "segueIdentifier" {
if myTextField.text = "words inside text field" {
let controller = segue.destinationViewController as! MyViewController
} else if myTextField.text = "different words in text field" {
let controller = segue.destinationViewController as! MyOtherViewController
}
}
}
So depending on the text inside of myTextField, the segue will be performed to either MyViewController or MyOtherViewController
And then in the #IBAction of whichever button you want to trigger the segue you would add performSegueWithIdentifier("segueIdentifier")

Related

How to pass different URL to webView from some buttons in swift?

I have some buttons in first view controller and a webView in second view controller. How to pass different url from different buttons to the webView? For example, the first button will leads to a google website and the second one is Facebook but using the same webView. Do I need to create different segues for each button or just one? If using just one, where should I start pulling that blue line (that line when you hold the control key)?
In first viewController:
class CafesView: UIViewController {
#IBOutlet weak var topBar: UIView!
#IBOutlet weak var button1: MDCFloatingButton!
#IBOutlet weak var button2: MDCRaisedButton!
#IBOutlet weak var button3: MDCRaisedButton!
#IBOutlet weak var button4: MDCRaisedButton!
#IBOutlet weak var button5: MDCRaisedButton!
#IBOutlet weak var button6: MDCRaisedButton!
#IBOutlet weak var button7: MDCRaisedButton!
#IBOutlet weak var button8: MDCRaisedButton!
#IBOutlet weak var button9: MDCRaisedButton!
let cafes = [
"Banana Joe's",
"College Eight Cafe",
"Global Village",
"Iveta",
"Oakes Cafe",
"Perk Coffee Bar",
"Stevenson Coffee House",
"Terra Fresca",
"Vivas"
]
var urlToPass: String!
override func viewDidLoad() {
super.viewDidLoad()
topBar.layer.shadowColor = UIColor.black.cgColor
topBar.layer.shadowOpacity = 0.5
topBar.layer.shadowOffset = CGSize(width: 0, height: 2)
topBar.layer.shadowRadius = 5
button1.layer.cornerRadius = 20
button2.layer.cornerRadius = 20
button3.layer.cornerRadius = 20
button4.layer.cornerRadius = 20
button5.layer.cornerRadius = 20
button6.layer.cornerRadius = 20
button7.layer.cornerRadius = 20
button8.layer.cornerRadius = 20
button9.layer.cornerRadius = 20
}
#IBAction func bananaJoes(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/banana-joes-menu.pdf"
}
#IBAction func collegeEightCafe(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/c8-menu.pdf"
}
#IBAction func globalVillage(_ sender: Any) {
urlToPass = "https://www.foodbooking.com/ordering/restaurant/menu?restaurant_uid=d368abee-3ccc-40d7-be7f-3ca5d4cbd513&glfa_cid=1263531392.1571083521&glfa_t=1571083566919"
}
#IBAction func iveta(_ sender: UIButton) {
urlToPass = "https://iveta.com/pages/iveta-ucsc-menu"
}
#IBAction func oakesCafe(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/oakes-menu-2019-20.pdf"
}
#IBAction func perkCoffeeBar(_ sender: UIButton) {
urlToPass = "https://google.com" //This url is just a placeholder
}
#IBAction func stevensonCoffeeHouse(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/stevenson-coffee-house-menu.pdf"
}
#IBAction func terraFresca(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/terra-fresca/pdf/terra-fresca-menu.pdf"
}
#IBAction func vivas(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/vivas-menu.pdf"
}
#IBAction func dismiss(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? CafesMenu else { return }
destination.detailURL = urlToPass
urlToPass = nil
}
}
In the second one:
import UIKit
import WebKit
class CafesMenu: UIViewController {
#IBOutlet weak var webView: WKWebView!
var detailURL: String?
override func viewDidLoad() {
super.viewDidLoad()
print("URL Requested: \(detailURL)")
}
override func viewWillAppear(_ animated: Bool) {
let url = URL(string: detailURL!)
let request = URLRequest(url: url!)
webView.load(request)
}
#IBAction func dismiss(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
}
}
What you need to do is use prepareForSegue:sender: to set a property in your destination view controller. prepareForSegue:sender: will be called before your initial view controller segues to any destination view controller. Within this function, we can check which button was pressed and set the appropriate URL in the destination view controller accordingly.
This approach will allow you to use any segue between your buttons and your destination view controller. This means, you simply have to drag the blue line from the buttons to the view controller you want to segue to.
1. Within your storyboard, create a segue between your first view controller and your destination view controller. This is done by holding control, clicking on the first view controller in the interface builder, and dragging over the destination view controller. Then choose a segue type:
Now, select this segue and give it the Identifier "InitialVCToDestinationVC" in the attributes inspector:
2. Make a property called urlToPass of type URL in your initial view controller:
class InitialViewController: UIViewController {
var urlToPass: URL!
#IBAction func googleButtonPressed(_ sender: Any) {
}
#IBAction func facebookButtonPressed(_ sender: Any) {
}
}
3. Make a property called receivedUrl in the destination view controller:
class DestinationViewController: UIViewController {
var receivedUrl: URL!
#IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: receivedUrl)
webView.load(request)
}
}
4. Set the urlToPass depending on which button is pressed and use the prepareForSegue:sender: function to set the destination view controller's url accordingly. Then, make use of performSegue(withIdentifier:sender:) to perform the segue with identifier InitialVCToDestinationVC.
class InitialViewController: UIViewController {
var urlToPass: URL!
#IBAction func googleButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.google.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
#IBAction func facebookButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.facebook.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? DestinationViewController else { return }
destination.receivedUrl = urlToPass
urlToPass = nil
}
}
5. (optional) Make use of the shouldPerformSegueWithIdentifier:sender: method within InitialViewController and check whether or not urlToPass is valid. If urlToPass is valid, perform the segue, else present an alert.
class InitialViewController: UIViewController {
...
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if let urlToPass = urlToPass {
// check if your application can open the NSURL instance
if !UIApplication.shared.canOpenURL(urlToPass) {
let alertController = UIAlertController(title: "Cannot open URL.", message: "This is an invalid URL.", preferredStyle: .alert)
let ok = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alertController.addAction(ok)
present(alertController, animated: true, completion: nil)
}
return UIApplication.shared.canOpenURL(urlToPass)
}
return false
}
}
End result:
Here's a link to the Xcode project I made the above gif from: https://github.com/ChopinDavid/PrepareForSegue
Try using the following code snippet to pass the urlParameter to second viewcontroller
class FirstViewController: UIViewController{
func googleActionButton() {
let vc = SecondViewController()
vc.urlToOpen = "www.google.com"
self.present(vc, animated: true, completion: nil)
}
func facebookActionButton() {
let vc = SecondViewController()
vc.urlToOpen = "www.facebook.com"
self.present(vc, animated: true, completion: nil)
}
}
class SecondViewController: UIViewController{
var urlToOpen = String()
override func viewDidLoad() {
super.viewDidLoad()
// set webview url to the 'urlToOpen' which you received from FirstViewController
}
}
First of all, create an enum WebURL with all the url cases that you want to open, i.e.
enum WebURL {
case google
case facebook
var url: String {
switch self {
case .google:
return "https://www.google.com"
case .facebook:
return "https://www.facebook.com"
}
}
}
Next, in FirstVC, in the UIButton's #IBAction open SecondVC using the WebURL instance corresponding to that particular button, i.e.
class FirstVC: UIViewController{
#IBAction func openGoogle(_ sender: UIButton) {
self.openSecondVC(with: WebURL.google.url)
}
#IBAction func openFacebook(_ sender: UIButton) {
self.openSecondVC(with: WebURL.facebook.url)
}
func openSecondVC(with urlString: String) {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC {
vc.urlString = urlString
self.present(vc, animated: true, completion: nil)
}
}
}
Then, use urlString in SecondVC to configure your webView, i.e.
class SecondVC: UIViewController {
var urlString: String?
override func viewDidLoad() {
super.viewDidLoad()
//Setup your webView using urlString here...
}
}

Text field is permanently in the second view controller upon segue

I have been working on an app that allows multiple text fields from the first view controller pass over to the second view controller upon pressing a button. However, the text fields are permanently in the second view controller when I only want them to be if the button is pressed. Here is the code for the first view controller! Any help is greatly appreciated.
class ViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var textField1: UITextField!
#IBAction func buttonTwo(_ sender: Any) {
if textField1.text != "" {
performSegue(withIdentifier: "segue", sender: self)
}
}
#IBAction func buttonOne(_ sender: Any) {
if textField.text != "" {
performSegue(withIdentifier: "segue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var secondController = segue.destination as! SecondViewController
secondController.myString1 = textField1.text!
secondController.myString = textField.text!
}
}
Here is the code in the second view controller:
class SecondViewController: UIViewController {
#IBOutlet weak var label: UILabel!
#IBOutlet weak var label1: UILabel!
var myString = String()
var myString1 = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
label1.text = myString1
// Do any additional setup after loading the view.
}
}
Image of storyboard
This happens because, prepare for segue will be called every time you perform some segue action.
You should manage to have a bool variable that helps you track, if any button is clicked or not, if the segue is performed from the click of the button, then only you will have to set the text while preparing for segue.
here is your updated viewController
class ViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var textField1: UITextField!
var isButtonClicked: Bool = false
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
/*reset isButtonClicked to false, when you back from second viewController */
isButtonClicked = false
}
#IBAction func buttonTwo(_ sender: Any) {
if textField1.text != "" {
isButtonClicked = true
performSegue(withIdentifier: "segue", sender: self)
}
}
#IBAction func buttonOne(_ sender: Any) {
if textField.text != "" {
isButtonClicked = true
performSegue(withIdentifier: "segue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if isButtonClicked {
var secondController = segue.destination as! SecondViewController
secondController.myString1 = textField1.text!
secondController.myString = textField.text!
}
}
}
Try and share your results.

How do I pass data from a UIViewController to UITabBarController?

In UIViewController:
class ViewController2: UIViewController {
var points = 0
var pressed = false
#IBOutlet weak var label: UILabel!
#IBAction func slider(_ sender: UISlider) {
number = Int(sender.value)
label.text = String(number)
}
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
}
}
I am trying to do something in a TabBarController if a button in a UIViewController is pressed and also add a number to the number in another TabBarConroller.
Image 1: This shows the connection between my ViewControllers.
Image 2: This shows the first two ViewControllers.)
Image 3: This shows the third and fourth ViewController
Here is my storyboard. I've put a few words to describe what I am trying to do in the images. Please tell me if you need a clearer description. Thank you!
If the ViewController is a child of the UITabBarController that you want to access, you can simply use tabBarController property of the UIViewController, e.g., use this to change selected controller to the first one:
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
self.tabBarController?.selectedIndex = 0
}
So let's say that you have a custom UITabBarController subclass, e.g.:
class CustomTabBarController: UITabBarController {
func acceptData(points: Int) {
print(">>> Accepted: \(points)")
// or do anything you need to do with it
}
}
Then you can pass it data as follows:
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
if let customTabController = self.tabBarController as? CustomTabBarController {
customTabController.acceptData(points: self.points)
}
}
UPDATE
Since it seems that the current VC is presented by one of the tabBarController child controllers, you will have to access it through the self.presentingViewController:
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
if let customTabController = self.presentingViewController?.tabBarController as? CustomTabBarController {
customTabController.acceptData(points: self.points)
}
}
UPDATE 2
Your screenshot are of a very poor quality, your explanation of the problem would require a clarification too, since it is really hard to understand what you try to do. So after the whole discussion in comments I guess this is it:
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
if let tabController = self.presentingViewController?.tabBarController,
let viewController3 = tabController.viewControllers?.filter({ $0 is ViewController3 }).first {
viewController3.acceptData(points: self.points)
}
}
You can pass data as normally
let vc:HomeVC = ApiUtillity.sharedInstance.getCurrentLanguageStoryboard().instantiateViewController(withIdentifier: "HomeVC") as! HomeVC
vc.tempCategoryArray = CategoryArray
self.navigationController?.pushViewController(vc, animated: true)
In your TabBarController class, take a variable say variableToBeSet
class TabBarController: UITabBarController
{
var variableToBeSet: Int = 0 // This is just an example. You can change it as per requirement.
// Rest of class implementation
}
Now in your ViewController :
#IBAction func submitbutton(_ sender: UIButton) {
pressed = true
let tabControllerInstance = self.tabBarController as! TabBarController
tabControllerInstance.variableToBeSet = localVariable // The value which you want to assign
}

How to send my score variable to another view controller?

After I click on a button I go to a new view controller.
I made it possible to make points with var score = 0 in a IBOutlet and to show to points I use Score.text = "\(++score)".
How can I pass the score to the 'Game over' screen/view controller to a label called "resultScore"?
Add an attribute secondViewController in the destination view controller, and use prepareForSegue
Current View Controller
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "segueTest") {
var svc = segue!.destinationViewController as secondViewController;
svc.toPass = textField.text
}
}
in secondViewController you can define one variable like String
var toPass:String!
In the secondViewController under the viewDidLoad function add this code
println(\(toPass))
One easy way to achieve that is you can use NSUserDefault for that.
first of all in your playScene when you are increasing your score you can store your score this way:
Score.text = "\(++score)"
NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "userScore")
After that in your next view controller you can get score this way:
resultScore = NSUserDefaults.standardUserDefaults().integerForKey("userScore")
Remember that type of your resultScore should be Int.
FirstViewController
#IBOutlet weak var textField: UITextField!
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let vc = segue.destinationViewController as? GameOverViewController {
vc.score = Int(textField?.text)
}
}
...
SecondViewController
var score: Int!
#IBOutlet weak var label: UILabel!
...
override func viewDidLoad() {
super.viewDidLoad()
label.text = String(score)
}
This method will call when button was pressed, and in this place you may set some properties for your second view controller

Swift: Pass multiple values between views

I have a view that has two text fields and a button.
#IBOutlet var inputURL: UITextField!
#IBOutlet var inputName: UITextField!
#IBAction func submitUrlButton(sender: AnyObject) {
}
and a second view that has two variables:
var submittedURL = ""
var submittedName = ""
println("Name \(submittedName)")
println("URL \(submittedURL)")
In Swift How do I pass the values entered in the two text fields and assign them to those variables in the second view?
Thanks
EDIT FOR THETOM:
import UIKit
class ViewController: UIViewController {
#IBOutlet var inputURL: UITextField!
#IBAction func submitBtn(sender: AnyObject) {
performSegueWithIdentifier("submissionSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
// Create a new variable to store the instance of the next view controller
let destinationVC = segue.destinationViewController as BrandsViewController
destinationVC.submittedURL.text = inputURL.text
}
}
You can use the method prepareForSegue.
In the first view (the one from which the segue is coming from) write the following code :
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
// Create a new variable to store the instance of the next view controller
let destinationVC = segue.destinationViewController as CustomViewController
destinationVC.submittedURL = inputURL.text
destinationVC.submittedName = inputName.text
}
Here CustomViewController is the custom class of the UIViewController to which the segue is going to.
To perform the segue programmatically in your button #IBAction do that :
#IBAction func buttonWasClicked(sender: AnyObject) {
performSegueWithIdentifier("submissionSegue", sender: self)
}
Since your view controllers are linked with segue you can override the prepareForSegue method in first view controller and pass data by doing so
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "secondViewController") { // here secondViewController is your segue identifier
var secondViewController = segue.destinationViewController as SecondViewController // where SecondViewController is the name of your second view controller class
secondViewController.submittedURL = inputURL.text
secondViewController.submittedName = inputName.text
}
}
And to performSegue inside your button action use perfromSegueWithIdentifier method
#IBAction func submitUrlButton(sender: AnyObject) {
//replace identifier with your identifier from storyboard
self.performSegueWithIdentifier("secondViewController", sender: self)
}
The simplest way of accessing values globally not neccessary to pass with segue
First View controller
import UIKit
var submittedURL:NSString? // declare them here
var submittedName:NSString? // Now these two variables are accessible globally
class YourViewController : UIViewController
{
#IBOutlet var inputURL: UITextField!
#IBOutlet var inputName: UITextField!
#IBAction func submitUrlButton(sender: AnyObject) {
if inputURL.text == "" && inputName.text == ""
{
//Show an alert here etc
}
else {
self.submittedURL.text = inputURL.text
self.submittedName.text = inputName.text
}
}
}
SecondView Controller
import UIKit
class SecondviewController: UIViewController
{
//inside viewDidload
println(submittedURL)
println(submittedName)
}