在 Swift 中的 TableView 和另一个 ViewController 之间传递数据

Pass data between TableView and another ViewController in Swift

我试图在 tableView 中显示一个事件列表,当用户按下其中一个事件时,它将打开另一个 viewController,其中包含有关该特定选择的更多信息。

这是tableView可以选择的选项:

import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase

class NewsfeedViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var ref:DatabaseReference!,
        posts = [eventStruct]()
    @IBOutlet weak var tableview: UITableView!
    var propertStruct : (Any)? = nil


    override func viewDidLoad() {
        super.viewDidLoad()
        loadNews()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loadNews() {
        ref = Database.database().reference()
        ref.child("events").queryOrderedByKey().observe(.childAdded, with: { (snapshot) in

            if let valueDictionary = snapshot.value as? [AnyHashable:String]
            {
                let title = valueDictionary["Title"]
                let location = valueDictionary["Location"]
                let date = valueDictionary["Date"]
                let description = valueDictionary["Description"]
                self.posts.insert(eventStruct(title: title, date: date, location: location, description: description), at: 0)
                self.tableview.reloadData()
            }
        })

    }

    /////////////////////////     Table View Content     \\\\\\\\\\\\\
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let label1 = cell.viewWithTag(1) as! UILabel
        label1.text = posts[indexPath.row].title
        let label2 = cell.viewWithTag(2) as! UILabel
        label2.text = posts[indexPath.row].location
        let label3 = cell.viewWithTag(3) as! UILabel
        label3.text = posts[indexPath.row].date
        return cell
    }

    func prepareForSegue(segue: UIStoryboardSegue, sender: eventStruct) {
        let secondViewController = segue.destination as? EventViewController
        secondViewController?.data = sender
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "showDetails", sender: posts[indexPath.row])
    }
    /////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\
}

struct eventStruct {
    let title: String!
    let date: String!
    let location: String!
    let description: String!


}

这里是 DetailsViewController,应该显示在之前 tableView 中选择的不同选项的标题:

import UIKit

class EventViewController: UIViewController {

    var data: eventStruct?
    @IBOutlet weak var titleLabel: UILabel!


    override func viewDidLoad() {
        super.viewDidLoad()
        print (data?.title as Any)
        self.titleLabel.text = self.data?.title

        // Do any additional setup after loading the view.
    }

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


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

问题在于,不是显示应存储在结构变量中的标题,而是始终返回 nil 值。

有人可以告诉我我做错了什么吗?我已尝试遵循所有提出的建议,但没有任何效果。

EventViewCotntroller 中的 属性 从 AnyData 更改为 eventStruct,例如:

var data: eventStruct?

然后在 table 控制器中:

func prepareForSegue(segue: UIStoryboardSegue, sender: eventStruct?) {

    let secondViewController = segue.destination as? EventViewController
    secondViewController?.data = sender

}

请记住,eventStruct 必须超出您的 TableViewControlle class 范围:

class TableViewController {
// controller logic 
}

struct eventStruct {
// struct body
}

尝试以下

在EventViewController

var propertStruct : (Any)? = nil

同时传递数据

secondViewController.propertStruct =   eventStruct(title : "", date : "", location: "", description: "")

输出

控制台同时分配

在SecondViewController中

你需要在 prepareforSegue 中传递 indexpath

 performSegue(withIdentifier: "showDetails", sender: indexPath)

func prepareForSegue(segue: UIStoryboardSegue, sender: Any) {
            let indexPath = sender as! IndexPath
            let eventStruct =  post[indexPath.row]
            let secondViewController = segue.destination as? EventViewController
            secondViewController?.data = sender as AnyObject

        }

您的 prepareForSegue 必须覆盖

的 UIViewController 方法
func prepare(for segue: UIStoryboardSegue, sender: Any?)

因此 NewsfeedViewController 中的方法应该是

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let secondViewController = segue.destination as? EventViewController
    secondViewController?.data = sender as? eventStruct
}

添加一些错误检查也是个好主意

第一个视图控制器

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if indexPath.row == 0
            {
                let objstory = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
            objstory.strd = imageView.image
            _ = self.navigationController?.pushViewController(objstory, animated: true)

            }
        }

SecondViewController

 var strd:UIImage!
@IBOutlet weak var imgprof: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        imgprof.image = strd


        // Do any additional setup after loading the view.
    }