perfrmSegueWithIdentifier() not working in swift iOS - ios

I don't get what I am doing wrong, I am trying to perform a push segue by an identifier so that I can move to other view-controller when an IF condition gets TRUE
the segue is always performed either I add this method : override func prepareForSegue()
#IBAction func btnClicked(sender: AnyObject) {
if(n.isEqualToString("mpc01") && p.isEqualToString("mpc01"))
{
self.performSegueWithIdentifier("login_to_dashboard", sender: nil)
}
else{
println("no data retrieved")
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "login_to_dashboard" {
// let secondViewController = segue.destinationViewController as VC_dashboard
println("performed segue")
}
else{
println("recieved other command")
}
}
my ViewController storyboard ID : SID_login
my SecondViewController storyboard ID : SID_dashboard
my Push Segue ID : login_to_dashboard
I want to perform segue by its ID only , not directly

You don't have the control when you use - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender. Instead, you can have control to trigger the segue or not by using this: - (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
The prepareForSegue just let you doing some custom works before triggering.

In prepareForSegue method you are checking if segue.identifier != "login_to_dashboard", I think you need to change it to == to perform segue.
#IBAction func btnClicked(sender: AnyObject) {
if(n.isEqualToString("mpc01") && p.isEqualToString("mpc01"))
{
self.performSegueWithIdentifier("login_to_dashboard", sender: nil)
}
else {
println("no data retrieved")
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "login_to_dashboard") {
let secondViewController = segue.destinationViewController as SecondViewController
println("performed segue")
}
else{
println("recieved other command")
}
}

You should use this method instead
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "login_to_dashboard" {
return true
}
else{
return false
}
}

this is very strange but since segue inherited from NSObject you can try:
if(segue.valueForKey("_identifier") as String == "login_to_dashboard"){
var targetController:VC_dashboard = segue.destinationViewController as VC_dashboard
targetController.doSomthing()
}

I did the mistake , solution to my question is to create a segue from view controller to other view controller rather a button to view-controller

I am sorry I am actually a beginner to xcode Swift , the question I asked was totally different to my segue issue. I actually created a segue directly from the button insteads of the first responser , thats why it always resulted to segue to another view-controller

Related

swift button press action loads tableview controller twice

I have a MeterTableviewController connected to two tableview controllers with two segues. The first segue LocationListSegue is connected from a button on the MeterTableviewController directly to the LocationListTableViewController. Another segue MetersListSegue connected from the top of the MeterTableViewController to the
MeterListTableviewController.
When I press on the location button, the LocationListTableViewController gets loaded twice.
I thought it is because I was calling it twice: once from the button IBAction and another time on Prepare, so I commented the code from Prepare, but it still loads it twice.
However the MeterListTableViewController gets loaded only once.
I dont know why the button press loads the controller twice. Can someone tell me?
#IBAction func chooseLocation(_ sender: Any) {
self.performSegue(withIdentifier: "LocationListSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
/*
if segue.identifier == "LocationListSegue"{
let viewController:LocationListTableViewController = segue.destination as! LocationListTableViewController
}
*/
if segue.identifier == "MetersListSegue"{
let viewController2:MeterListTableViewController = segue.destination as! MeterListTableViewController
}
}
You have added a segue as well as segue action from button, remove one of them
Remove story board segue and change your code with my code. This is enough for you.
#IBAction func chooseLocation(_ sender: Any) {
let tableViewController = self.storyboard?.instantiateViewController(withIdentifier: "your identifier") as! MeterListTableViewController
self.navigationController?.pushViewController(tableViewController, animated: true)
}
If you want to use segue remove IBAction for UIButton and write this code.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "LocationListSegue"{
let viewController:LocationListTableViewController = segue.destination as! LocationListTableViewController
} else if segue.identifier == "MetersListSegue"{
let viewController2:MeterListTableViewController = segue.destination as! MeterListTableViewController
}
}

Changing label text of second ViewController upon clicking button in first ViewController

I'm new to Swift and to iOS Development. I currently have 2 ViewControllers, a button in the first and a label in the second one. I've connected the first button to the second ViewController and the transition works.
Now, when I try changing the label's text I get the error:
fatal error: unexpectedly found nil while unwrapping an Optional
value
.
Here you find my prepare function in the first ViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! SecondViewController
vc.secondResultLabel.text = "Testing"
}
}
Can it be that the label in the second ViewController is somehow protected ?
Thanks for the help
You need to pass the String to the SecondViewController instead of directing setting it, as the UILabel has not been created yet.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! SecondViewController
vc.secondResultLabelText = "Testing"
}
}
And in your SecondViewController viewDidLoad method set the UILabel to be the string
var secondResultLabelText : String!
override func viewDidLoad() {
secondResultLabelText.text = secondResultLabelText
}
add a string variable in the second view controller
var labelText: String!
in second view controller also (in viewDidLoad)
self.secondResultLabel.text = self.labelText
then first view controller prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! SecondViewController
vc.labelText = "Testing"
}
}
this is because second view controller's UILabel Outlet is not being initialized yet in prepare for segue
Rikh's answer is the same, both his answer and mine are the same
Welcome aboard :)
Your problem is that your SecondViewController, and more specifically vc.secondResultLabelText is not initiated when you call prepare, so secondResultLabel is actually nil at that time.
You need to add a variable to your SecondViewController like so:
var labelText: String = ""
And then set that value instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! SecondViewController
vc.labelText = "Testing"
}
}
In viewWillAppear or viewDidLoad on your SecondViewController you can then use that value for your secondResultLabelText which is now ready, connected, and won't crash
secondResultLabelText.text = labelText
Hope that helps.
First take a global variable in SecondViewController... eg I took "secondViewControllerVariable". Then get the text you want to display in your SecondViewController.
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "mySegue"
{
let vc = segue.destination as! SecondViewController
vc.secondViewControllerVariable = "Your string you get in FirstViewController"
}
}
And then in your SecondViewController, in viewDidLoad method set the UILabel to be the string
var secondViewControllerVariable : String! // You have to declare this first in your SecondViewController Globally
override func viewDidLoad()
{
vc.secondResultLabelText.text = secondViewControllerVariable
}
That's it. Happy Coding.

Swift passing arrays between 2 tableviews. Returns nil instead

I am pretty new to SWIFT coding. My intention is to pass 2 arrays with values from Viewcontroller1 to Viewcontroller2. But it returns me nil value in Viewcontroller2. Can someone advise me please?
Here is the partial code in ViewController1.
#IBAction func solve(sender: AnyObject) {
//pass information to the nextviewcontroller
func prepareForSegue ( segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "Solve") {
var svc = segue!.destinationViewController as ViewController2
svc.toPass = self.force
svc.toPass2 = stiffness
}
}
Here is the partial code in ViewController2.
class ViewController2: UITableViewController {
var toPass:[String]!
var toPass2:[String]!
override func viewDidLoad() {
super.viewDidLoad()
println(self.toPass)
println(self.toPass2)
// Do any additional setup after loading the view.
}
The full code can be found in here. https://github.com/cherrythia/SWIFTpassingarrays/blob/master/README.md
I have created project similar to yours (using your github link) and #Sebastian Wramba is correct. You have to separate these two functions:
#IBAction func solve_pressed(sender: AnyObject) {
self.performSegueWithIdentifier("Solve", sender: sender)
}
override func prepareForSegue ( segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "Solve") {
var svc = segue.destinationViewController as ViewController2
svc.toPass = self.force
svc.toPass2 = stiffness
}
}
Okay, solved (pun intended). You have to give your segue identifier, in this particular case, "Solve". In your first view controller, select push to View Controller2, go to the fourth tab and set identifier to "Solve".

Dismiss modal, then immediately push view controller

How can I dismiss a modal and then immediately push another view?
I am adding this code in a didSelectRowAtIndexPath:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ChatTableViewController *chatVC = (ChatTableViewController*)[storyboard instantiateViewControllerWithIdentifier:#"chatVC"];
[self dismissViewControllerAnimated:YES completion:^{
[[self navigationController] pushViewController:chatVC animated:YES];
}];
The modal view dismisses, but nothing happens after. Any ideas?
You can't push a view controller into a view dismissed, if it's dismissed it disappears so it's not logical to push another view, cause the parent view controller is deleted. Probably you have this:
- ViewController 1 --> Modal ViewController 2 -->Wanted to dismiss VC2 and push VC3
What you have to do is
- ViewController 1 --> Modal ViewController 2 --> Dismiss VC2 --> Push VC3 on VC1
You can do it with notifications. The most efficient way is to use delegates, create a delegate on VC2 that notifies V1 when it dismisses and then just push VC3.
No, it cant be done that quickly as far as I know, you need to add a delay betwwn the dissmiss and the navigation of another controller, only then will it execute else it would crash an error saying, trying to push a controller while dismissing other
This answer tries to solve the original problem asked above.
A,B,C viewControllers. A is the root VC of a navigationController.
A-> modally_presents -> B-> dismissing_modally_prsented_B_and_automatically_pushing -> C
Note: All presentation and dismissals are done using segues.
I have marked important sequence of actions.
class CViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
/************************************************************/
protocol BDelegate: class {
func BDelegateFunc(someRandomString: String)
}
class BViewController: UIViewController {
weak var delegate: BDelegate?
var name: String?
override func viewDidLoad() {
super.viewDidLoad()
name = "swappy"
}
#IBAction func btnClicked(_ sender: Any) {
// 3 DISMISS using segue
performSegue(withIdentifier: "unwindToAViewController", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 4
print(segue.identifier)
}
deinit {
// 6
print(String(describing: type(of: self)) + #function)
delegate?.BDelegateFunc(someRandomString: name!)
}
}
/************************************************************/
class AViewController: UIViewController, BDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnClicked(_ sender: Any) {
// 1 MODAL
performSegue(withIdentifier: "presentBFromA", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "presentBFromA" {
// 2
let vc = segue.destination as! BViewController
vc.delegate = self
} else if segue.identifier == "showCFromA" {
// 8 This will finally push C in navigationController
print(segue.identifier)
}
}
#IBAction func unwindToAViewController(segue: UIStoryboardSegue) {
// 5
print(#function)
}
func BDelegateFunc(someRandomString: String) {
// 7
print(someRandomString)
performSegue(withIdentifier: "showCFromA", sender: self)
}
}

Prepare for segue error in lldb

I'm calling it like this
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "hat") {
let itemVC: ItemViewController = sender.destinationViewController as ItemViewController
itemVC.myDelegate = self
itemVC.nameArray = self.nameArray
}
}
but the lldb freezes up once I call to go to the next view controller. Any idea whats going on?
I believe you want:
segue.destinationViewController
instead of:
sender.destinationViewController

Resources