数据未在视图控制器Swift之间传输

时间:2015-11-27 03:59:53

标签: ios swift swift2 tableview uistoryboardsegue

当EventTableViewController进入UserEventViewController或EventViewController时,由于标签等未更新为传输的信息,因此不会传输数据。我试过修理它但它仍然无法正常工作。请帮助。

任何帮助都会非常感谢。 链接到项目: https://www.dropbox.com/s/1d4d8opuxzpcuk4/TicketekApp.zip?dl=0

代码:

//  EventTableViewController.swift



import UIKit

class EventTableViewController: UITableViewController {
// MARK: Properties

var events = [Event]()
var isAdmin = true
override func viewDidLoad() {
    super.viewDidLoad()

    // Use the edit button item provided by the table view controller.
    navigationItem.leftBarButtonItem = editButtonItem()

    // Load any saved events, otherwise load sample data.
    if let savedEvents = loadEvents() {
        events += savedEvents
    } else {
        // Load the sample data.
        loadSampleEvents()
    }
}

func loadSampleEvents() {
    let photo1 = UIImage(named: "event1")!
    let event1 = Event(name: "ACDC", photo: photo1, rating: 4, price: 500.0, eventDescription: "Album", album: "Album1")!

    let photo2 = UIImage(named: "event2")!
    let event2 = Event(name: "Cold Play", photo: photo2, rating: 5, price: 500.0, eventDescription: "Album", album: "Album1")!

    let photo3 = UIImage(named: "event3")!
    let event3 = Event(name: "One Direction", photo: photo3, rating: 3, price: 500.0, eventDescription: "Album", album: "Album1")!

    events += [event1, event2, event3]
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return events.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    // Table view cells are reused and should be dequeued using a cell identifier.
    let cellIdentifier = "EventTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! EventTableViewCell

    // Fetches the appropriate event for the data source layout.
    let event = events[indexPath.row]

    cell.nameLabel.text = event.name
    cell.photoImageView.image = event.photo
    cell.ratingControl.rating = event.rating
    cell.priceLabel.text = event.album

    return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let index = self.tableView.indexPathForSelectedRow?.row
    //use the index to know which cell you selected

    //check for your condition here something like
    if isAdmin {
        performSegueWithIdentifier("eventViewControllerSegue", sender: self)
    } else {
        performSegueWithIdentifier("userEventTableViewControllerSegue", sender: self)
    }
}

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want item to be editable.
    return true
}


// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        events.removeAtIndex(indexPath.row)
        saveEvents()
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create new instance of  class, add to the array, and add a new row to the table
    }
}


/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

}
*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/


// MARK: - Navigation

// preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "eventViewControllerSegue"  {
        let eventDetailViewController = segue.destinationViewController as! EventViewController

        // Get the cell that generated this segue.
        if let selectedEventCell = sender as? EventTableViewCell {
            let indexPath = tableView.indexPathForCell(selectedEventCell)!
            let selectedEvent = events[indexPath.row]
            eventDetailViewController.event = selectedEvent

        }
    } else  if segue.identifier == "userEventTableViewControllerSegue"  {
        let eventDetailViewController = segue.destinationViewController as! UserEventViewController

        // Get the cell that generated this segue.
        if let selectedEventCell = sender as? EventTableViewCell {
            let indexPath = tableView.indexPathForCell(selectedEventCell)!
            let selectedEvent = events[indexPath.row]
            eventDetailViewController.event = selectedEvent

        }
    }
    else if segue.identifier == "AddItem" {
        print("Adding new event.")
    }
}


@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
    if let sourceViewController = sender.sourceViewController as? EventViewController, event = sourceViewController.event {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            // Update an existing event.
            events[selectedIndexPath.row] = event
            tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
        } else {
            // Add a new event.
            let newIndexPath = NSIndexPath(forRow: events.count, inSection: 0)
            events.append(event)
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
        }
        // Save the events.
        saveEvents()
    }
}

// MARK: NSCoding

func saveEvents() {
    let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(events, toFile: Event.ArchiveURL.path!)
    if !isSuccessfulSave {
        print("Failed to save events...")
    }
}

func loadEvents() -> [Event]? {
    return NSKeyedUnarchiver.unarchiveObjectWithFile(Event.ArchiveURL.path!) as? [Event]
}
}

2 个答案:

答案 0 :(得分:1)

毫无疑问,Shripada的回答是正确的。但是,我想解释为什么你的代码无法正常工作。

您正在使用performSegueWithIdentifier("eventViewControllerSegue", sender: self)方法调用tableView:didSelectRowAtIndexPath。请注意这里发送者:self是ViewController而不是tableCell。现在,当它触发prepareForSegue时,您正尝试使用let selectedEventCell = sender as? EventTableViewCell访问所选单元格。但是,发件人不是EventTableCell。这就是为什么你得到一个零值而你的if条件失败。

一个简单的解决方法是使用tableView.indexPathForSelectedRow!中的prepareForSegue获取所选的tableViewCell,并将相应的数据传递给destinationViewController。

  let eventDetailViewController = segue.destinationViewController as! EventViewController

  // Get the indexPath of selected cell
  let indexPath = self.tableView.indexPathForSelectedRow!

  let selectedEvent = events[indexPath.row]
  eventDetailViewController.event = selectedEvent

答案 1 :(得分:0)

您通常希望找到与所选行相关的事件。因此,您需要记录选择哪一行。引入一个名为:

的变量
var currentlySelectedIndex = 0

到你的EventTableViewController

然后将同一类中didSelectRow委托方法的实现更改为 -

覆盖func tableView(tableView:UITableView,didSelectRowAtIndexPath indexPath:NSIndexPath){

//Record the row selected
currentlySelectedIndex = indexPath.row

//check for your condition here something like
if isAdmin {
    performSegueWithIdentifier("eventViewControllerSegue", sender: self)
} else {
    performSegueWithIdentifier("userEventTableViewControllerSegue", sender: self)
}

}

第三,您需要利用此选定的行索引来获取正确的事件对象:

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "eventViewControllerSegue"  {
      let eventDetailViewController = segue.destinationViewController as! EventViewController
      //Get the associated event
      eventDetailViewController.event = events[currentlySelectedIndex]
    } else  if segue.identifier == "userEventTableViewControllerSegue"  {
      let eventDetailViewController = segue.destinationViewController as! UserEventViewController
      //Get the associated event
      eventDetailViewController.event = events[currentlySelectedIndex]
    }
    else if segue.identifier == "AddItem" {
      print("Adding new event.")
    }
  }

这将解决您的问题。