如何从 UITableView 数据(UIImage 和 String)提取到另一个 ViewController
How extract from UITableView data (UIImage and String) to another ViewController
我想将一个TableView中包含的存储数据传递给另一个ViewController。我的 customCell 有一个 UIImage 和一个字符串。
当用户按下单元格时,我想显示带有 UIImage 的 "detail view controller" 和包含所选单元格信息的标签。
这是我的代码:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var dataTableView: UITableView!
var myList = [dataList]()
var textToBeSent: String = ""
var selectedImage: UIImage?
var selectedLabel: String?
//Load Items To List
func loaditems(){
let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")
myList += [item1,item2]
}
//var list = ["Documento 1", "Documento 2", "Documento 3"]
override func viewDidLoad() {
super.viewDidLoad()
if let savedData = loadSavedItems(){
myList += savedData
} else {
loaditems()
}
//dataTableView.register(UITableViewCell.self, forCellReuseIdentifier: "reusablecell")
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return myList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "prototype", for: indexPath) as! PrototypeCell
let itemsinCell = myList[indexPath.row]
cell.imageItem.image = itemsinCell.photoList
cell.itemDescription.text = String(itemsinCell.itemDescription)
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
myList.remove(at: indexPath.row)
dataTableView.reloadData()
}
saveToSavedData()
}
这是我要传递某个单元格数据的函数。
数据来自使用解码器 NSCoder 存储在 "DataList" 中的 Swift 文件。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row \(indexPath.row) selected")
selectedImage! = myList[indexPath.row].photoList
selectedLabel! = myList[indexPath.row].itemdescription
performSegue(withIdentifier: "selectedRowSegue", sender: myList[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"){
let chosenRowViewController = segue.destination as! chosenRowViewController
chosenRowViewController.image3 = selectedImage?.photoList
chosenRowViewController.label3 = selectedLabel?.itemDescription
}
}
展开 segue 以便用之前的数据填充单元格
ViewController:
//Unwinde Segue
@IBAction func unWindlToList(sender: UIStoryboardSegue){
if let sourceViewController = sender.source as? ProcessViewController, let item = sourceViewController.item{
let newIndexPath = IndexPath(row: myList.count, section: 0)
myList.append(item)
dataTableView.insertRows(at: [newIndexPath], with: .automatic)
}
saveToSavedData()
}
//Archive Data
func saveToSavedData(){
NSKeyedArchiver.archiveRootObject(myList, toFile: (dataList.fileFolder?.path)!)
}
//Unarchive Data
func loadSavedItems() -> [dataList]?{
return NSKeyedUnarchiver.unarchiveObject(withFile: (dataList.fileFolder?.path)!) as? [dataList]
}
}
class PrototypeCell: UITableViewCell {
@IBOutlet weak var itemDescription: UILabel!
@IBOutlet weak var imageItem: UIImageView!
}
您在 didSelectRowAt
中犯了一个错误,在调用 performSegue
时,您必须传递控制器,即 sender
,在您的情况下,它是您当前的 [=14] =],所以你必须写 self
作为发送者控制器。因此,您更正后的方法将如下代码片段所示:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row \(indexPath.row) selected")
selectedImage! = myList[indexPath.row].photoList
selectedLabel! = myList[indexPath.row]
performSegue(withIdentifier: "selectedRowSegue", sender: self)
}
只需将 prepare(for segue: UIStoryboardSegue, sender: Any?)
函数替换为以下代码
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"), let list = sender as? dataList {
let chosenRowViewController = segue.destination as! chosenRowViewController
chosenRowViewController.image3 = list.photoList
chosenRowViewController.label3 = list.itemDescription
}
}
有几件事很突出。
1-var myList = [dataList]()
dataList是一个Class
,classes要大写。应该是var myList = [DataList]()
2- 你把它作为 class 属性 但它没有在你发布的代码中的任何地方使用,那么你为什么添加它,它的目的是什么? var textToBeSent: String = ""
3- 你有这 2 个 class 属性 变量
var selectedImage: UIImage?
var selectedLabel: String?
保存来自 [myList]
的数据,但你真的不需要它们,因为你可以使用 prepareForSegue
中的 dot notation
访问来自 [myList]
的数据(阅读prepareForSegue 中注释掉的代码)。
4- 在 prepareForSegue 中你有 let chosenRowViewController = segue.destination as! chosenRowViewController
。 ChosenRowViewController 是一个 class,它应该像这样大写:
let chosenRowViewController = segue.destination as! ChosenRowViewController // it's capitalized after the as!
这里的代码稍微整理了一下。
@IBOutlet weak var dataTableView: UITableView!
var myList = [DataList]()
func loaditems(){
let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")
myList.append(item1)
myList.append(item2)
}
override func viewDidLoad() {
super.viewDidLoad()
// everything you already have inside here...
}
// your tableView datasource methods...
5- 因为你使用 prepareForSegue
你不需要 didSelectRowAt indexPath
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"){
// get the indexPath for the selectedRow
let indexPath = tableView.indexPathForSelectedRow
let chosenRowViewController = segue.destination as! ChosenRowViewController
chosenRowViewController.image3 = myList[indexPath!.row].photoList // use dot notation to access the photoList property
chosenRowViewController.label3 = myList[indexPath!.row].itemDescription // use dot notation to access the itemDescription property
}
}
我想将一个TableView中包含的存储数据传递给另一个ViewController。我的 customCell 有一个 UIImage 和一个字符串。 当用户按下单元格时,我想显示带有 UIImage 的 "detail view controller" 和包含所选单元格信息的标签。
这是我的代码:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var dataTableView: UITableView!
var myList = [dataList]()
var textToBeSent: String = ""
var selectedImage: UIImage?
var selectedLabel: String?
//Load Items To List
func loaditems(){
let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")
myList += [item1,item2]
}
//var list = ["Documento 1", "Documento 2", "Documento 3"]
override func viewDidLoad() {
super.viewDidLoad()
if let savedData = loadSavedItems(){
myList += savedData
} else {
loaditems()
}
//dataTableView.register(UITableViewCell.self, forCellReuseIdentifier: "reusablecell")
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return myList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "prototype", for: indexPath) as! PrototypeCell
let itemsinCell = myList[indexPath.row]
cell.imageItem.image = itemsinCell.photoList
cell.itemDescription.text = String(itemsinCell.itemDescription)
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
myList.remove(at: indexPath.row)
dataTableView.reloadData()
}
saveToSavedData()
}
这是我要传递某个单元格数据的函数。 数据来自使用解码器 NSCoder 存储在 "DataList" 中的 Swift 文件。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row \(indexPath.row) selected")
selectedImage! = myList[indexPath.row].photoList
selectedLabel! = myList[indexPath.row].itemdescription
performSegue(withIdentifier: "selectedRowSegue", sender: myList[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"){
let chosenRowViewController = segue.destination as! chosenRowViewController
chosenRowViewController.image3 = selectedImage?.photoList
chosenRowViewController.label3 = selectedLabel?.itemDescription
}
}
展开 segue 以便用之前的数据填充单元格 ViewController:
//Unwinde Segue
@IBAction func unWindlToList(sender: UIStoryboardSegue){
if let sourceViewController = sender.source as? ProcessViewController, let item = sourceViewController.item{
let newIndexPath = IndexPath(row: myList.count, section: 0)
myList.append(item)
dataTableView.insertRows(at: [newIndexPath], with: .automatic)
}
saveToSavedData()
}
//Archive Data
func saveToSavedData(){
NSKeyedArchiver.archiveRootObject(myList, toFile: (dataList.fileFolder?.path)!)
}
//Unarchive Data
func loadSavedItems() -> [dataList]?{
return NSKeyedUnarchiver.unarchiveObject(withFile: (dataList.fileFolder?.path)!) as? [dataList]
}
}
class PrototypeCell: UITableViewCell {
@IBOutlet weak var itemDescription: UILabel!
@IBOutlet weak var imageItem: UIImageView!
}
您在 didSelectRowAt
中犯了一个错误,在调用 performSegue
时,您必须传递控制器,即 sender
,在您的情况下,它是您当前的 [=14] =],所以你必须写 self
作为发送者控制器。因此,您更正后的方法将如下代码片段所示:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Row \(indexPath.row) selected")
selectedImage! = myList[indexPath.row].photoList
selectedLabel! = myList[indexPath.row]
performSegue(withIdentifier: "selectedRowSegue", sender: self)
}
只需将 prepare(for segue: UIStoryboardSegue, sender: Any?)
函数替换为以下代码
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"), let list = sender as? dataList {
let chosenRowViewController = segue.destination as! chosenRowViewController
chosenRowViewController.image3 = list.photoList
chosenRowViewController.label3 = list.itemDescription
}
}
有几件事很突出。
1-var myList = [dataList]()
dataList是一个Class
,classes要大写。应该是var myList = [DataList]()
2- 你把它作为 class 属性 但它没有在你发布的代码中的任何地方使用,那么你为什么添加它,它的目的是什么? var textToBeSent: String = ""
3- 你有这 2 个 class 属性 变量
var selectedImage: UIImage?
var selectedLabel: String?
保存来自 [myList]
的数据,但你真的不需要它们,因为你可以使用 prepareForSegue
中的 dot notation
访问来自 [myList]
的数据(阅读prepareForSegue 中注释掉的代码)。
4- 在 prepareForSegue 中你有 let chosenRowViewController = segue.destination as! chosenRowViewController
。 ChosenRowViewController 是一个 class,它应该像这样大写:
let chosenRowViewController = segue.destination as! ChosenRowViewController // it's capitalized after the as!
这里的代码稍微整理了一下。
@IBOutlet weak var dataTableView: UITableView!
var myList = [DataList]()
func loaditems(){
let item1 = dataList(photoList: UIImage.self(), itemDescription: "Descripcion Aqui")
let item2 = dataList(photoList: UIImage.self(), itemDescription: "Aqui tmb")
myList.append(item1)
myList.append(item2)
}
override func viewDidLoad() {
super.viewDidLoad()
// everything you already have inside here...
}
// your tableView datasource methods...
5- 因为你使用 prepareForSegue
你不需要 didSelectRowAt indexPath
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "selectedRowSegue"){
// get the indexPath for the selectedRow
let indexPath = tableView.indexPathForSelectedRow
let chosenRowViewController = segue.destination as! ChosenRowViewController
chosenRowViewController.image3 = myList[indexPath!.row].photoList // use dot notation to access the photoList property
chosenRowViewController.label3 = myList[indexPath!.row].itemDescription // use dot notation to access the itemDescription property
}
}