Initiating segue from error: Receiver has no segue with identifier
You shouldn't call the method like this:
ViewController().successfulLogin(Username: Username)
The above code will init a new instance of ViewController. You should use delegate pattern or completion handler to call the successfulLogin
method.
Example of using completion handler:
In ViewController.swift
:
@IBAction func loginButton() {
login(Username: UserNameField.text!, Password: PasswordField.text!) { username in
self.successfulLogin(Username: username)
}
}
In Login.swift
:
func login(Username: String, Password: String, completion: @escaping (String) -> Void) {
var request = URLRequest(url: URL(string: "web address")!)
request.httpMethod = "POST"
let postString = "action=login&username=\(Username)&password=\(Password)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
if responseString! == "success" {
print("Good")
// Send to new page \\
completion(Username)
}
if responseString! == "fail" {
print("failed")
// Alert Error \\
func alertPopup(title: String, message: String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
alertController.addAction(UIAlertAction(title: "Try Again", style: UIAlertActionStyle.default, handler: nil))
}
// Add to main Queue \\
OperationQueue.main.addOperation{
alertPopup(title: "Error", message: "Invalid Login")
}
}
}
task.resume()
}
NSInvalidArgumentException - receiver has no segue with identifier
i fixed it! 1. make sure the right storyboard is selected in Xcode(if you rename the storyboard change it in the project summary). then delete the app on the simulator and restart
Xcode, where to assign the segue identifier
Segue Identifier is not the same as storyboard ID, storyboard ID used when you want to create a View Controller based on that specific storyboard -and it has to be unique, unlike the segue identifier-.
If you already know how to create a segue, you can skip this part.
Adding a segue between two viewControllers:
From the Interface Builder, press the ctrl and drag between the two View Controllers that you want to link (make sure that you are dragging from the view controller itself, not the its main view). You should see:
Choose the "Show" -for instance-, the output should look like this:
As shown above, the arrow that surrounded by the red rectangle is the segue.
Additional note: if you selected the "Show" option, you have to embed your first view Controller in a Navigation Controller (select your first viewController -> Editor -> Embed In -> Navigation Controller), the output should looks like:
Because the "Show" means pushing into a navigation controller stack.
Assigning an identifier for the segue:
Select the segue, from the attribute inspector you'll see "Identifier" text field, that's it! make sure to insert the exact same name that used in performSegueWithIdentifier
.
If you don't know where to find the attribute inspector, it is on the top right looks like:
Furthermore:
For adding multiple segues from one View Controller, follow the same process (ctrl + drag from the first controller to each other View Controller), the output should looks like:
In this case, you might face the issue how to recognize which segue has been performed, overriding prepare(for:sender:)
method is the solution, you can make the checking based on the segue identifier
property:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "firstSegueIdentifier") {
// ...
} else if (segue.identifier == "secondSegueIdentifier") {
//...
}
}
which would be the name that you have added to the segue in the storyboard.
Can't make a segue in Side Menu
I found solution here.
Quick answer:
Storyboard have to looks like "Nav Controller -> [Main View Controller] -> (modal) Side Menu Nav Controller -> (embed/root view controller relationship) Table View Controller (with menu options) -> (push) other view controllers"
Thanks for help @Abhishek Jadhav your code works fine!
ObjectiveC Segue between TableView and ViewController
in didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:@"showDetails" sender:self];
}
in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showDetails"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
ViewController *destViewController = segue.destinationViewController;
destViewController.details = data [indexPath.row];
}
}
Related Topics
How to Add a Toolbar Above the Keyboard
Uialertview First Deprecated iOS 9
How to Delete All Cookies of Uiwebview
How to Set Up Push Notifications in Swift
Resize Uiimage to 200X200Pt/Px
Uicollectionview Reloaddata Not Functioning Properly in iOS 7
How to Push and Present to Uiviewcontroller Programmatically Without Segue in iOS Swift 3
How to Make Uitextview Height Dynamic According to Text Length
Change Status Bar Background Color in Swift 3
iOS 11 Disable Password Autofill Accessory View Option
Changing the Development Language in Xcode
iOS 13: Swift - 'Set Application Root View Controller Programmatically' Does Not Work
How to Combine React Native with Socket.Io
Swift 3 - How to Verify Class Type of Object
Nsurlsession: How to Increase Time Out for Url Requests