从自定义表格视图单元格获取数据到另一个 VC?
Posted
技术标签:
【中文标题】从自定义表格视图单元格获取数据到另一个 VC?【英文标题】:Getting data from custom tableview cell to another VC? 【发布时间】:2017-12-15 12:00:45 【问题描述】:寻求一些帮助或朝着正确的方向轻推,因为我似乎无法弄清楚这一点。我正在尝试将自定义表格视图单元格上的电子邮件标签中的文本获取到另一个 VC 中,在那里我将有一个联系表。我在 tableview 单元格上有一个按钮,所以理想情况下,这将进入一个新的 VC,在那里我可以访问电子邮件字段,但对于那个特定的单元格。我已经研究过使用 preparetoseugue 函数来实现 indexpath.row 索引,但到目前为止还没有运气。
这是我的自定义表格视图单元格:
//
// RentalCell.swift
// Login
//
// Created by George Woolley on 02/12/2017.
// Copyright © 2017 George Woolley. All rights reserved.
//
import UIKit
import Foundation
import Firebase
import MessageUI
class RentalCell: UITableViewCell, MFMailComposeViewControllerDelegate
var rental: Rental!
@IBOutlet weak var rentalTitleLbl: UILabel!
@IBOutlet weak var rentalPriceLbl: UILabel!
@IBOutlet weak var rentalTypeLbl: UILabel!
@IBOutlet weak var bondLbl: UILabel!
@IBOutlet weak var rentLbl: UILabel!
@IBOutlet weak var dateAvalLbl: UILabel!
@IBOutlet weak var petsLbl: UILabel!
@IBOutlet weak var descriptionLbl: UILabel!
@IBOutlet weak var emailField: UILabel!
@IBOutlet weak var rentalImage: UIImageView!
func configureCell(rental: Rental, image: UIImage?)
self.rental = rental
self.rentalTitleLbl.text = rental.title
self.rentalPriceLbl.text = rental.price
self.rentalTypeLbl.text = rental.rentalType
self.bondLbl.text = rental.bond
self.rentLbl.text = rental.price
self.dateAvalLbl.text = rental.dateAval
self.petsLbl.text = rental.pets
self.descriptionLbl.text = rental.description
self.emailField.text = rental.email
if image != nil
//Image already in cache
self.rentalImage.image = image
else
// download image from Firebase
let ref = Storage.storage().reference(forURL: rental.imageURL!)
ref.getData(maxSize: 2 * 1024 * 1024, completion: (data, error) in
if error != nil
print("An error has occured downloading image")
else
print("Image downloaded")
if let imageData = data
if let img = UIImage(data: imageData)
self.rentalImage.image = img
RentalTableViewVC.imageCache.setObject(img, forKey: rental.imageURL! as NSString)
)
这是我的 tableViewVC:
//
// MainVC.swift
// Login
//
import UIKit
import Firebase
import FirebaseDatabase
class AvertisingVC: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate
@IBOutlet weak var titleField: UITextField!
@IBOutlet weak var dateAvalField: UITextField!
@IBOutlet weak var rentalTypeField: UITextField!
@IBOutlet weak var petsField: UITextField!
@IBOutlet weak var furnishedField: UITextField!
@IBOutlet weak var bondField: UITextField!
@IBOutlet weak var rentField: UITextField!
@IBOutlet weak var descriptionField: UITextView!
@IBOutlet weak var addImage: UIImageView!
@IBOutlet weak var emailField: UITextField!
var imageSelected = false
let datePicker = UIDatePicker()
var imagePicker: UIImagePickerController!
var databaseRef:DatabaseReference? //reference to firebase dba
let rentalTypes = ["Room in shared house", "Entire House","Room Share", "Apartment", "Cottage", "Other"]
let petsAllowed = ["Yes", "No"]
let rentalTypePicker = UIPickerView()
let petsAllowedPicker = UIPickerView()
func numberOfComponents(in pickerView: UIPickerView) -> Int
return 1
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
return rentalTypes.count
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
return rentalTypes[row]
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
rentalTypeField.text = rentalTypes[row]
rentalTypeField.resignFirstResponder()
func createDatePicker()
//toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//done button
let done = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(datePickerDonePressed))
toolbar.setItems([done], animated: false)
//add picker to text field
dateAvalField.inputAccessoryView = toolbar
dateAvalField.inputView = datePicker
//format picker for date
datePicker.datePickerMode = .date
@objc func datePickerDonePressed()
//formate date
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
let dateString = dateFormatter.string(from: datePicker.date)
dateAvalField.text = "\(dateString)"
self.view.endEditing(true)
func setupRentalTypePicker()
rentalTypeField.inputView = rentalTypePicker
rentalTypePicker.dataSource = self
rentalTypePicker.delegate = self
rentalTypeField.textAlignment = .center
rentalTypeField.placeholder = "Select rental type"
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
if let image = info[UIImagePickerControllerEditedImage] as? UIImage
addImage.image = image
imageSelected = true
else
print("Invalid image from picker")
imagePicker.dismiss(animated: true, completion: nil)
override func viewDidLoad()
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
//Firebase Ref
databaseRef = Database.database().reference().child("Rentals") //can add .child(string:root) to add root dir to dba
//Date Picker
createDatePicker()
//rentalTypePicker
setupRentalTypePicker()
@IBAction func backBtnPressed(_ sender: Any)
self.dismiss(animated: true, completion: nil)
@IBAction func submitForm(_ sender: Any) // Send data to firebase on submit
guard let img = addImage.image, imageSelected == true else
let alert = UIAlertController(title: "You must upload one image to proceed", message: "It's recommended you upload one image before continuing.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
return
//Upload image with unique ID as a key
if let imageData = UIImageJPEGRepresentation(img, 0.2)
let imageUID = UUID().uuidString
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
DataService.ds.StorageREF.child(imageUID).putData(imageData, metadata: metaData) (metadata, error) in
if error != nil
print("Error occured uploading data to firebase")
else
print("Successfully uploaded image")
let downloadURL = metadata?.downloadURL()?.absoluteString
if let url = downloadURL
self.postDataToFirbase(imgURL: url)
let alertController = UIAlertController(title: "Success!", message: "You have successfully listed a rental", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Close Alert", style: .default, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
func postDataToFirbase(imgURL: String)
let data: Dictionary<String, AnyObject> = [
"title": titleField.text as AnyObject,
"price": rentField.text as AnyObject,
"description": descriptionField.text as AnyObject,
"bond": bondField.text as AnyObject,
"date": dateAvalField.text as AnyObject,
"type": rentalTypeField.text as AnyObject,
"pets": petsField.text as AnyObject,
"imageURL": imgURL as AnyObject,
"email": emailField.text as AnyObject
]
//Post data
let postDataTo = DataService.ds.DBrefRentals.childByAutoId()
postDataTo.setValue(data)
//Clear screen
titleField.text = ""
rentField.text = ""
descriptionField.text = ""
bondField.text = ""
rentalTypeField.text = ""
dateAvalField.text = ""
petsField.text = ""
furnishedField.text = ""
emailField.text = ""
addImage.image = #imageLiteral(resourceName: "house")
@IBAction func addImagePressed(_ sender: Any)
present(imagePicker, animated: true, completion: nil)
【问题讨论】:
Passing Data between View Controllers的可能重复 只是关于你的主题行的注释......你永远不应该考虑从应用程序的视觉元素中获取数据,除非它是响应用户编辑的简单数据模型更新。如果您正在寻找要传递的信息源,请从与您的单元格匹配的Rental
对象中获取它。
谢谢菲利普。这真的是我一直在寻找的。我知道我正在尝试做的更多的是一种变通方法/hacky 方法,已经研究出如何通过 indexpath 的值从 Rental Object 获取值。
【参考方案1】:
在“Sender”类中声明一个变量
例子:
var valueName: String?
接下来的事情是为 segue 做准备
示例:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.destination is ValuesTableViewController
let vc = segue.destination as? ValuesTableViewController
vc?.valueName = "Some string u want to send"
其中 ValuesTableViewController 是 Receivers View Controller 类
最后要做的是在代码中调用 segue 方法,您希望将用户重定向到下一个屏幕。
示例:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let cell = tableView.cellForRow(at: indexPath) as! UnitTableViewCell
if let valueName = cell.valueLabel.text
print(valueName)
sendingName = valueName
if let color = cell.leftColorView.backgroundColor
sendingColor = color
self.performSegue(withIdentifier: "goToValues", sender: self)
如果用户单击 TableView 中的一个单元格,您会将他重定向到下一个屏幕,这只是一个示例,您也可以在其他情况下使用它。
最后一步:在receiver ViewController 中创建一个变量
var valueName: String?
然后你可以在任何你喜欢的地方使用它
快乐编码
【讨论】:
以上是关于从自定义表格视图单元格获取数据到另一个 VC?的主要内容,如果未能解决你的问题,请参考以下文章