在 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.
}
我试图在 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
必须覆盖
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.
}