Swift pass data between VCs - ios

i'm new to Swift and i would like to know why this piece of code i translated from Obj-C doesn't work here.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "scoreDetail" {
let indexPath = self.tableView.indexPathForSelectedRow()
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
let itemVC: ScoreVC = segue.destinationViewController as ScoreVC
itemVC.detailItem = object
}
}
Here is the storyboard. I have a Show Replace segue from the cell to the UINavigatorController
I get this error as soon as i click on a UITableViewCell

The problem has nothing to do with Swift. The destinationViewController is the navigation controller, not your ScoreVC, so the code you translated that from shouldn't have worked either (if it had the same setup). It should look like this,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "scoreDetail" {
let indexPath = self.tableView.indexPathForSelectedRow()
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
let nav : UINavigationController = segue.destinationViewController
let itemVC: ScoreVC = nav.topViewController as ScoreVC
itemVC.detailItem = object
}
}

Related

UITableView Not Using Cell as Sender

I'm trying to segue and pass data (from UITableView to a UIViewController). My code is
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "IndividualAchievementsSegue" {
let destination = segue.destinationViewController as? IndividualAchievementsViewController
let cell = sender as! UITableViewCell
let selectedRow = AchievementsTable.indexPathForCell(cell)!.row
destination!.viaSegue = achievements[selectedRow]
print(selectedRow)
}
}
but the line let cell = sender as! UITableViewCell is throwing
Could not cast value of type 'ProgramName.AchievementsViewController' to 'UITableViewCell'
I have also tried
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "IndividualAchievementsSegue" {
let destination = segue.destinationViewController as? IndividualAchievementsViewController
let selectedRow = AchievementsTable.indexPathForSelectedRow!.row
destination!.viaSegue = achievements[selectedRow]
print(selectedRow)
}
}
That fails because it finds nil unwrapping the optional during achievements[selectedRow] since that apparently gives me a nil from let selectedRow = AchievementsTable.indexPathForSelectedRow!.row
I think the problem is that your segue is connected with your AchievementsViewController to IndividualAchievementsViewController instead of UITableViewCell to IndividualAchievementsViewController. Check in the storyboard for that and correct the segue with TableCell to IndividualAchievementsViewController.
So the solution was to go into DidSelectrowAtIndexPath and remove DeselectRowAtIndexPath, which was in there twice by accident. Then use the following
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "IndividualAchievementsSegue" {
let destination = segue.destinationViewController as? IndividualAchievementsViewController
let selectedRow = AchievementsTable.indexPathForSelectedRow?.row
destination!.viaSegue = achievements[selectedRow!]
print(selectedRow)
}
}

apple swift slideoutMenu indexPath

I am creating a slide menu for ios but I'm having problems
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let DestVC = segue.destinationViewController as ViewController
let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow()!
DestVC.varView = indexPath.row
}
why doesn't this code work?
You need to make optional cast cause segue.destinationViewController is UIViewController that can't be always casted to its subclass
Try this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard let DestVC = segue.destinationViewController as? ViewController else { return }
let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow()!
DestVC.varView = indexPath.row
}

Passing object with prepareForSegue Swift

I am trying to pass an object to another scene with prepareForSegue()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
var nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow() {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
And I have currentVehicle object to catch these object. But, when I try to run, it brokes and get error about downcasting.
Error EDIT
Could not cast value of type 'XXX.DisplayViewController'
(0x1082dcd80) to 'XXX.VehicleDetailsTableViewController'
(0x1082dc9a0). (lldb)
You have to give the segue an identifier in the storyboard.(say mySegue)
Using Xcode 10 swift 4.x(Also works with Xcode 9 & 8 , swift 3.x)
override func prepare(for segue: UIStoryboardSegue, sender: Any?){}
Is called for all segues being called from your current UIViewController. So the identifier is to differentiate the different segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" ,
let nextScene = segue.destination as? VehicleDetailsTableViewController ,
let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
If you are using Using Xcode 7, swift 2.x
Then use this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" {
var nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
}
Place a breakpoint after nextScene and see if it is being triggered by clicking any cell in the TableView. If it isn't then the identifier name u provided in the storyboard must be different then the one given here.
In swift 3.0 Xcode 8 beta 6
AnyObject has been renamed to Any?
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
let nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
}
In Swift 3, Xcode 8
Just don't use "identifier". I don't know why but "segue.identifier" is always nil. I just used prepare method like this and works!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let secondController = segue.destination as? SecondController {
secondController.anyItemInSecondController = self.anyItemInFirstController
}
What that error is telling you is that segue.destinationViewController isn't a VehicleDetailsTableViewController. We don't have enough details to tell you why.
Check your segues and make sure they're all pointing to the correct place, and always check the identifier of your segue before you perform a cast.
if segue.identifier == "theNameOfYourSegue" // then do your cast

prepareForSegue UICollectionView not working (swift)

I’ve tried to push segue by using UICollectionView (show image form MasterView to DeatilView) but is not working. Xcode also doesn’t show any error message. What’s wrong with my code. I need some advice.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let indexPath = self.collectionView?.indexPathForCell(sender as! UICollectionViewCell) {
let detailVC = segue.destinationViewController as! DetailMenuViewController
detailVC.picFood = self.collection[indexPath.row]
collection is empty array get data form json
[title = self.nameFood.title], it is working in DetailMenuViewController.swift but not image on code above.
You need to add the UICollecitonViewDelegate
func collectionView(collection: UICollectionView, selectedItemIndex: NSIndexPath)
{
self.performSegueWithIdentifier("showDetail", sender: self)
}
After that add
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let indexPath = self.collectionView?.indexPathForCell(sender as! UICollectionViewCell) {
let detailVC = segue.destinationViewController as! DetailMenuViewController
detailVC.picFood = self.collection[indexPath.row]
}
}
}

Swift Segue not working

I have a school project to make a swift app. I'm very new to swift and trying to pass data through the segue from a tableview to another view.
Here is the project file Download Here.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PopularDetails" {
let detailsViewController = segue.destinationViewController as DetailsViewController
let selectedIndexPath = popularTableView.indexPathForSelectedRow()
detailsViewController.shots = shots[selectedIndexPath.row]
}
}
}
.indexPathForSelectedRow() returns an optional. You have to unwrap it, before you can access its properties. Try:
let selectedIndexPath = popularTableView.indexPathForSelectedRow()
detailsViewController.shots = shots[selectedIndexPath!.row]
(see the exclamationmark)
Although #gutenmorgenuhu is correct, it's probably better practice to use:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PopularDetails" {
if let detailsViewController = segue.destinationViewController as? DetailsViewController {
if let selectedIndexPath = popularTableView.indexPathForSelectedRow() {
detailsViewController.shots = shots[selectedIndexPath.row]
}
}
}
}

Resources