Swift - Trying to set up a share button - swift

I'm trying to set up a share button from a time I previously coded it. I must be missing something, but I'm not sure what. Can you help? This is on a different view controller than the main one.
import UIKit
class MoreViewController: UIViewController, UITabBarDelegate, UITextFieldDelegate {
#IBAction func shareKnockingBuddy(_ sender: AnyObject) {
let messageToSend = "Here is a message. \(doorsKnocked)"
let vc = UIActivityViewController(activityItems: [messageToSend], applicationActivities: nil)
self.present(vc, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Here's my error: On the App delegate it's "Thread 1: signal SIGABRT". On the message thingy on the bottom, it says "* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController shareKnockingBuddy:]: unrecognized selector sent to instance 0x7fe282c02eb0'
* First throw call stack:"

Notice the error is about UIViewController and not your MoreViewController class. This means you did not set th proper class name for the view controller in your storyboard. Change it to MoreViewController.

Related

Unrecognized selector sent to instance for Bar Button

I'm making a Twitter app on Xcode and have encountered a frustrating error.
I'm tryna make the Tweet bar button present modally.
When I run the code it crashes if I click "Tweet"
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Twitter.TweetViewController _finishDecodingLayoutGuideConnections:]: unrecognized selector sent to instance 0x7fb1a25512c0'
*** First throw call stack:
libc++abi.dylib: terminating with uncaught exception of type NSException
import UIKit
class TweetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var tweetTextView: UITextView!
#IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func Tweet(_ sender: Any) {
if (!tweetTextView.text.isEmpty) {
TwitterAPICaller.client?.postTweet(tweetString: tweetTextView.text, success:{ self.dismiss(animated: true, completion: nil)
}, failure: { (error) in
print("Error posting tweet \(error)")
self.dismiss(animated: true, completion: nil)
})
} else {
self.dismiss(animated: true, completion: nil)
}
}
I looked up people with similar issues but could not find an solution that helped.
Verify the IBOutlets and IBActions are properly connected. These crash happens when the XIB and Class files are not properly connected.
Try to remove the connections and add it again. Also rename the property names if the error persist.

Swift Interesting NSExceptionError When Passing Data Forward

I have a really simple question here that I cannot manage to solve. This code works perfectly fine, leading me to the fifth view controller.
#objc func OnbtnPlusTouched()
{
let uivc = storyboard!.instantiateViewController(withIdentifier: "FifthViewController")
navigationController!.pushViewController(uivc, animated: true)
}
However, I want to pass the data locationName from this viewcontroller to the next one. Thus I used this code segment:
#objc func OnbtnPlusTouched()
{
let vc = FifthViewController(nibName: "FifthViewController", bundle: nil)
vc.locationName = locationName
navigationController?.pushViewController(vc, animated: true)
}
But now I am getting this error as soon as I enter this function in my app:
libc++abi.dylib: terminating with uncaught exception of type
NSException and Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Could not load NIB in
bundle: 'NSBundle
I would appreciate any help, thank you!
Try this instead
#objc func OnbtnPlusTouched() {
guard let uivc = storyboard!.instantiateViewController(withIdentifier: "FifthViewController") as? FifthViewController else {
return
}
uivc.locationName = locationName
navigationController!.pushViewController(uivc, animated: true)
}

Swift: addGestureRecognizer for UIView class

I use this code:
class StarClass: UIView {
#IBOutlet weak var bgStar: UIView!
class func createMyClassView() -> StarClass {
let myClassNib = UINib(nibName: "Star", bundle: nil)
let nW = myClassNib.instantiate(withOwner: nil, options: nil)[0] as! StarClass
nW.bgStar.layer.cornerRadius = 15
nW.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleStar(sender:))))
return nW
}
#objc func handleStar(sender: UITapGestureRecognizer) {
print("iosLog STAR")
}
}
After run, if I clicked on the view, I get error below:
2018-07-10 11:11:50.496349+0430 Ma[23098:89853] +[Ma.StarClass
handleStarWithSender:]: unrecognized selector sent to class
0x10ef5cac0 2018-07-10 11:11:50.513392+0430 Ma[23098:89853] *
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '+[Ma.StarClass
handleStarWithSender:]: unrecognized selector sent to class
0x10ef5cac0'
* First throw call stack:...
There seems to be a problem with the line :
nW.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleStar(sender:))))
Here, inside a class function, self refers to the Class type, not its object. But you are adding the gesture recogniser on an object. The solution here would be to do this:
nW.addGestureRecognizer(UITapGestureRecognizer(target: nW, action: #selector(handleStar(sender:))))

App crashing when instantiating ViewController from different storyboard

I'm writing in Swift 3 (latest Xcode)
I'm controlling, if the user is logged in (async tasks checking parameters between device and database).
If the response says, that the device is invalid, I'm showing the login screen. Looks like this:
extension UIViewController {
func forceLogin() {
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
let navController = UINavigationController(rootViewController: controller)
self.present(navController, animated: true, completion: nil)
}
}
Login storyboard looks just like this.
When user successfully logs in, the function starts:
DispatchQueue.main.async {
self.dismiss(animated: true, completion: nil)
}
The dismissal may happen in first and second ViewController.
Imagine the situation:
User logs in and comes back to main application after dismissing 2nd VC
Device is being deleted from DB
After check, user needs to log in again
forceLogin() and...
libc++abi.dylib: terminating with uncaught exception of type NSException
It happens when self.present(navController, animated: true, completion: nil) is used.
I have some ideas what may cause the crash but I'm not sure:
Creating navigation controller in code instead in storyboard
Dismiss is not enough - storyboard somehow stays in memory and can't be instantiated again
What can cause the problem and how can I avoid crashing?
If any more info is necessary, please ask.
I always forget this. Remeber to place your interface tasks like this:
DispatchQueue.main.async {
self.present(navController, animated: true, completion: nil)
}

How to call perform segue method from another class?

I want to perform segue from View B to View C and I am calling method in class A.
My segue method in Class B is-
//ViewController B
func nextViewAction() -> Void {
self.performSegueWithIdentifier("nextview", sender: self)
}
And I am calling it in Class A like this-
//ViewController A
#IBAction func sideMenuAction(sender: AnyObject) {
ViewClassB().nextViewAction()
}
But it crashing- Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'nextview''
Have you set the name nextview for the segue between Controller B and Controller C? You can check by clicking on the segue between the two controllers, and then checking the Identifier value in the Attributes Inspector.
What you can have is move to the third viewcontroller from first viewcontroller by skipping the second one use the code below..
class MyViewController: UIViewController, UINavigationControllerDelegate {
var viewControllerToInsertBelow : UIViewController?
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.delegate = self
}
func pushTwoViewControllers() {
if let viewController2 = self.storyboard?.instantiateViewControllerWithIdentifier("id1"),
let viewController3 = self.storyboard?.instantiateViewControllerWithIdentifier("id2") { //change this to your identifiers
self.viewControllerToInsertBelow = viewController2
self.navigationController?.pushViewController(viewController3, animated: true)
}
}
//MARK: - UINavigationControllerDelegate
func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
if let vc = viewControllerToInsertBelow {
viewControllerToInsertBelow = nil
let index = navigationController.viewControllers.indexOf(viewController)!
navigationController.viewControllers.insert(vc, atIndex: index)
}
}
}
Reference : SO Post
Don't need to do any other code just use
notification observer it will solve your problem.
Thank you
I think you cannot trigger segue action from AViewController because what
performSegue does is that :
Initiates the segue with the specified identifier from the current view controller's storyboard file.
Try implementing segue from A to C