简体   繁体   中英

Swift: Pass data to static table view

I'm starting to study Swift with the help of this Apple's guide: https://itunes.apple.com/it/book/app-development-with-swift/id1219117996

Now i am stuck on a small problem that i would like to understand how to solve, but from the guide it is not very clear.

This is the situation

在此处输入图片说明

It's a simple application, that show a list of emojis with a description. A tap on emoji-cell it should open the static table view and show the emoji's information.

Result

From the guide

“You'll need to pass the Emoji object from EmojiTableViewController to the static table view controller when a cell is tapped. Start by creating a new file, and define a UITableViewController subclass called "AddEditEmojiTableViewController". Remember to delete or comment out any table view data source methods in the file. In Main.storyboard, set the static table view's "Custom Class" to "AddEditEmojiTableViewController". Add a property to the AddEditEmojiTableViewController class called emoji with a type of Emoji. Within the prepare(for segue:) method of EmojiTableViewController, you'll check the identifier, downcast the destination view controller, access the object(s) to pass, then assign the properties:”

AddEditEmojiTableViewController file

import UIKit

class AddEditEmojiTableTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if let emoji = emoji{
            symbolTextfield.text = emoji.symbol
            nameTextfield.text = emoji.name
            descriptionTextfield.text = emoji.description
            usageDescription.text = emoji.usage
        }

    }

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

    var emoji: Emoji! = nil

    @IBOutlet weak var symbolTextfield: UITextField!
    @IBOutlet weak var nameTextfield: UITextField!
    @IBOutlet weak var descriptionTextfield: UITextField!
    @IBOutlet weak var usageDescription: UITextField!

}

The prepare function of the EmojiTableViewController file, as described in the guide. (EditEmoji is the segue from the cell to the static table view)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "EditEmoji" {
        let indexPath = tableView.indexPathForSelectedRow!
        let emoji = emojis[indexPath.row]
        let addEditEmojiTableViewController = segue.destination
        as! AddEditEmojiTableViewController
        addEditEmojiTableViewController.emoji = emoji
    }
}

Kepping the prepare function in this way, when i tap on a cell i have this error-crash

Could not cast value of type 'UINavigationController' .. to 'Emoji.AddEditEmojiTableTableViewController' ....
... Could not cast value of type 'UINavigationController' ... to 'Emoji.AddEditEmojiTableTableViewController' ...

So, looking on stackoverflow, i modified the function in this way, and now it works.

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "EditEmoji"{
        let indexPath = tableView.indexPathForSelectedRow!
        let emoji = emojis[indexPath.row]
        let test1 = segue.destination as! UINavigationController
        let test2 = test1.topViewController as! AddEditEmojiTableTableViewController
        test2.emoji = emoji
    }
 }

So my question is: Is the guide wrong? Is the guide not updated with the latest Swift version?

The guide needs to be updated , you shouldn't have put AddEditEmojiTableViewController inside of a navigation controller. If you had connected the segue directly from the EmojiTableViewController to AddEditEmojiTableViewController it would have worked as expected.

In your first example the segue.destination is a UINavigationController, which has nothing to do with the AddEditEmojiTableViewController class. So force casting class. So force casting segue.destination to AddEditEmojiTableViewController` will always fail.

In the second snippet the destination of your code, it works, since following the tree of view controllers: test1 is the navigation controller, and its root vc is test2 which is AddEditEmojiTableViewController .

Without looking to the guide if the desintation VC in IB is inserted inside a navigationController then it's incorrect and you'right to use

let addEditEmojiTableViewController = segue.destination as! UINavigationController

but if you edited it then vice versa

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM