I want to scan a QR code (doing this example: http://humberaquino.me/qrcode-scanning-in-swift/), however I have a problem with this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let barcodeViewController: BarcodeViewController = segue.destinationViewController as! BarcodeViewController
barcodeViewController.delegate = self
}
I got this:
When I change this to as!, I'm getting:
Thread 1: signal SIGABRT on this line.
If you have more than one segue on that view controller, it may be another one firing. checking segue.identifier is one way of making sure you're on the right one. If the behaviour is based on the class you can do this :
if let barcodeViewController = segue.destinationViewController as? BarcodeViewController
{
barcodeViewController.delegate = self
}
Related
I have included images to hopefully make this easier to understand. My FirstViewController has a collection view with a list of users from my firebase database.When I click on the users I am segued to a DetailedViewController that has more information about the user that was clicked. Within that viewController, the goal is to click on the compose button and segue to a viewController that allows me to chat with the user, whose profile I clicked on.
I have gotten as far as this for segueing from DetailedViewController to Message user 1.
#IBAction func SendMessage(_ sender: Any) {
performSegue(withIdentifier: "chat", sender: self)
}
I am not sure how to make sure I am sending the particular user I click on a message.
This is how I am passing data from FirstViewController to DetailedViewController.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "details" {
if let indexPaths = self.CollectionView!.indexPathsForSelectedItems{
let vc = segue.destination as! BookDetailsViewController
let cell = sender as! UICollectionViewCell
let indexPath = self.CollectionView!.indexPath(for: cell)
let post = self.posts[(indexPath?.row)!] as! [String: AnyObject]
let Booked = post["title"] as? String
vc.Booked = Booked
print(indexPath?.row)
} }
One route to take is in your DetailViewController class, or whatever class you have implementing performSegue(withIdentifier:, sender:), add this:
override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "chat", let dest = segue.destination as? ChatViewController else {
return
}
dest.user = self.user
}
I don't know how you have the user declared but if user is an object, do what I have above. If you're saying user as a way to umbrella multiple properties you want to pass.. do this:
dest.name = self.name
dest.number = self.number
//etc
prepare(for segue:, sender:) allows you to intercept any segue from it's class and set up whatever variables needed before the performSegue(...) executes. To target your code to a specific segue/destination/situation, make sure your code runs a check on those constraints before executing; otherwise the code will execute on all segues implemented in the class. In my example, I used your segue's identifier as that check.
I have a navigation controller as the initial view. It goes to VC1 which has 3 buttons, and each button is tied to an action that sets a parameter in VC2 before invoking performSegueWithIdentifier("goNow", sender: nil). I have this in my VC1 too.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "goNow") {
if let sView: SViewController = segue.destinationViewController as? SViewController {
sView.action = self.action
}
}
}
When invoked, VC2 appears for a few seconds and it terminates with EXC_BAD_ACCESS.
I am not extremely familiar with Swift, but I know that there are some questions when attempting to compare strings. Instead of using:if (segue.identifier == "goNow")
~ edit ~
Setting the class in Interface Builder (storyboard) for the destination view controller.
Create a String Variable using the segue.identifier value and compare the two like this:
let segueID = String(segue.identifier)
let segueToOpen = "goNow"
let isEqual = (segueID == segueToOpen)
// Now your if statement
if isEqual {
// ...
}
Also, you might want to consider separating the logic in the next if statement to read something like:
let sView: SViewController = segue.destinationViewController
Here is an excerpt from RayWenderlick's site and using the as operator:
This is a totally dumb question I am sure. I have a viewcontroller that is inside a navigation controller that is inside a TabBarController. Apple says this is the right way to implement that setup. However, how can I prepareForSeque to that complex and send data to the first ViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "presentActionItems" {
println("preparing")
let tabBarController:actionItemsTabController = segue.destinationViewController as! actionItemsTabController
let navigationController = ???
let viewController = ???
viewController.givenURL = actionItemsURL
}
}
I am sure this is an easy question, can I have some help.
Try this in your TabController's viewDidLoad after passing it your data
let firstViewController : UIViewController = self.viewControllers.objectAtIndex(0).topViewController;
firstViewController.this = self.this;
firstViewController.that = self.that;
I have a tableview with buttons each containing a tag (according to indexPath.row), and when I press a particular button the details of the contents of that cell (which relates to a class called EventEntity) is meant to be passed through a 'prepareForSegue' method to another screen.
The value is assigned in the 'infoButtonDidPress' method as shown below:
func infoButtonDidPress(sender: UIButton){
eventPressed = eventEntities[sender.tag]
println (eventPressed.name) // prints the name, all good here.
}
The problem is that when I assign the contents of eventPressed to the destinationVC in 'prepareForSegue', they are nil. Code below:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "infoButtonSegue"){
var svc = segue.destinationViewController as! EventDetailsViewController;
println (eventPressed.name) // NOPE.
svc.name = eventPressed.name //also NOPE!
}
eventPressed is declared above viewDidLoad:
var eventPressed: EventEntity! = EventEntity()
The error I get when I try either of those lines with the 'NOPE' comment is 'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Appname.EventEntity name]: unrecognized selector sent to instance 0x7fa280e16a50' error
Whats going on here?
Thanks in advance!
UPDATE
I have moved performWithSegue to the infoButtonDidPress method, but I am now unable to reference the destinationViewController.
My infoButtonDidPress now looks like this:
func infoButtonDidPress(sender: UIButton){
let eventPressed = eventEntities[sender.tag]
var destinationViewController: UIViewController = self.destinationViewController as EventDetailsViewController
// error: the current VC does not have a member named destinationViewController
self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}
As you discovered, prepareForSegue is happening before infoButtonDidPress is called.
To fix this, instead of wiring the segue from the prototype cell in your tableView, wire it from the viewController icon at the top.
See this: How to wire segue from ViewController icon
Make sure to set the identifier to "infoButtonSegue". Then call the segue from infoButtonDidPress after you have set the value for eventPressed:
func infoButtonDidPress(sender: UIButton){
eventPressed = eventEntities[sender.tag]
self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}
And then, in prepareForSegue pass the value to the destination view controller:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "infoButtonSegue") {
let dvc = segue.destinationViewController as! EventDetailsViewController
dvc.name = eventPressed.name
}
}
I have two table views (DayTVC & AddDayTVC). The title of the navigation item in the DayTVC represents the selected week. Is there a way to transfer the title of the navigation item (DayTVC) to a label on the AddDayTVC? I tried this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "addDay" {
let destinationController = segue.destinationViewController as AddDayTableViewController
let sender = sender as DayTableViewController
destinationController.nameLabel.text = sender.navigationItem.title
}
}
But every time I trie to get to AddDayTVC I get the following error
Thread 1: EXC_Breakpoint (code=EXC_I386_BPT, subcode=0x0)"
for this line
let destinationController = segue.destinationViewController as AddDayTableViewController
Thanks in advance!
Since you're triggering the segue with a UIBarButtonItem, the sender will be that button and the cast:
let sender = sender as DayTableViewController
will fail and throw the indicated exception. Since this code is (probably) located in the DayTableViewController, why not just use self instead?