我正在制作一个应用程序,它有一个图片的新闻源(HomeViewController)。用户可以轻触每个图像,这些图像将转到SiteViewController,SiteViewController有一个空数据表视图和一个按钮,当单击该按钮时,这些图像将转到ContextSheetViewController,用户可以在其中上载他们在新闻源中单击的图像的数据。然后,用户按upload,此数据(siteCodeTextView、arecodetextView、trenchTextView)将保存到firebase,并返回到SiteViewController。然后,我想检索刚刚在SiteViewController的表视图中上载的图像的siteCodeTextView的数据值。但是,当我在ContextSheetViewController中按upload时,出现错误:在展开可选值时意外找到nil。我的sheetId正在SiteViewController中打印nil,所以我不确定如何正确检索它?有什么帮助吗?
以下是我的相关视图控制器的故事板:
站点视图控制器的代码:
class SiteViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var sheets = [Sheet]()
var users = [User]()
var sheetId: String!
var postId: String!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
loadSheets()
print(postId)
print(sheetId)
}
func loadSheets() {
Api.Sheet.REF_SHEETS.child(self.postId!).observe(.childAdded, with: {
snapshot in
Api.Sheet.observeSheets(withSheetId: snapshot.key, completion: {
sheet in
// self.fetchUser(uid: sheet.uid!, completed: {
print("sheet id: \(sheet.id)")
print("sheet uid: \(sheet.uid)")
self.sheets.append(sheet)
self.tableView.reloadData()
// })
})
})
}
func fetchUser(uid: String, completed: @escaping () -> Void ) {
Api.User.observeUser(withId: uid, completion: {
user in
self.users.append(user)
completed()
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SheetSegue" {
let sheetVC = segue.destination as! SheetViewController
let sheetId = sender as! String
sheetVC.sheetId = sheetId
}
}
}
extension SiteViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sheets.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SheetCell", for: indexPath) as! SiteTableViewCell
let sheet = sheets[indexPath.row]
print("sheet id: \(sheet.id)")
print("sheet uid: \(sheet.uid)")
// let user = users[indexPath.row]
// cell.user = user
cell.sheet = sheet
cell.delegate = self
return cell
}
}
extension SiteViewController: SiteTableViewCellDelegate {
func goToSheetVC(sheetId: String) {
performSegue(withIdentifier: "SheetSegue", sender: sheetId)
}
}
ContextSheetViewController的代码:
class ContextSheetViewController: UIViewController {
@IBOutlet weak var siteCodeTextView: UITextField!
@IBOutlet weak var areaCodeTextView: UITextField!
@IBOutlet weak var trenchTextView: UITextField!
@IBOutlet weak var uploadArtefactImage: UIImageView!
@IBOutlet weak var artefactImageView: UIImageView!
var selectedImage: UIImage?
var postId: String!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleSelectPhoto))
uploadArtefactImage.addGestureRecognizer(tapGesture)
uploadArtefactImage.isUserInteractionEnabled = true
}
@objc func handleSelectPhoto() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
@IBAction func uploadButton_TouchUpInside(_sender: Any) {
if let profileImg = self.artefactImageView.image, let imageData = UIImageJPEGRepresentation(profileImg, 0.1) {
let photoIdString = NSUUID().uuidString
print(photoIdString)
let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("sheets").child(photoIdString)
storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
let photoUrl = metadata?.downloadURL()?.absoluteString
self.sendDataToDatabase(photoUrl: photoUrl!)
})
} else {
ProgressHUD.showError("Sheet Image can not be empty!")
}
}
func sendDataToDatabase(photoUrl: String) {
// let ref = Database.database().reference()
let sheetsReference = Api.Sheet.REF_SHEETS
// let sheetsReference = ref.child("sheets")
let newSheetId = sheetsReference.childByAutoId().key
let newSheetReference = sheetsReference.child(newSheetId)
guard let currentUser = Auth.auth().currentUser else {
return
}
let currentUserId = currentUser.uid
newSheetReference.setValue(["uid": currentUserId, "photoUrl": photoUrl, "siteCodeTextView": siteCodeTextView.text!, "areaCodeTextView": areaCodeTextView.text!, "trenchTextView": trenchTextView.text!], withCompletionBlock: {
(error, ref) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
let postSheetRef = Api.Sheet.REF_SHEETS.child(self.postId!).child(newSheetId)
// let postSheetRef = Api.Sheet.REF_SHEETS.child("post-sheets").child(self.postId).child(newSheetId)
postSheetRef.setValue(true, withCompletionBlock: { (error, ref) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
})
ProgressHUD.showSuccess("Success")
self.clean()
self.navigationController?.popViewController(animated: true)
})
}
func clean() {
self.siteCodeTextView.text = ""
self.uploadArtefactImage.image = UIImage(named: "upload")
self.artefactImageView.image = UIImage(named: "image")
}
}
extension ContextSheetViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("did Finish Picking Media")
if let image = info["UIImagePickerControllerOriginalImage"] as? UIImage{
artefactImageView.image = image
// selectedImage = image
// uploadArtefactImage.image = image
}
dismiss(animated: true, completion: nil)
}
}
SiteTableViewCell的代码:
protocol SiteTableViewCellDelegate {
func goToSheetVC(sheetId: String)
}
class SiteTableViewCell: UITableViewCell {
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var siteSheetLabel: UILabel!
@IBOutlet weak var nameLabel: UILabel!
var delegate: SiteTableViewCellDelegate?
var sheet: Sheet? {
didSet {
updateView()
}
}
var user: User? {
didSet {
setupUserInfo()
}
}
func updateView() {
siteSheetLabel.text = sheet?.siteCodeTextView
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func setupUserInfo() {
nameLabel.text = user?.username
if let photoUrlString = user?.profileImageUrl {
let photoUrl = URL(string: photoUrlString)
profileImageView.sd_setImage(with: photoUrl, placeholderImage: UIImage(named: "placeholderImg"))
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.siteSheetLabel_TouchUpInside))
siteSheetLabel.addGestureRecognizer(tapGesture)
siteSheetLabel.isUserInteractionEnabled = true
}
@objc func siteSheetLabel_TouchUpInside() {
print(sheet?.id)
if let id = sheet?.id{
delegate?.goToSheetVC(sheetId: id)
}
}
override func prepareForReuse() {
super.prepareForReuse()
profileImageView.image = UIImage(named: "placeholderImg")
}
}
最佳答案
从您所展示的罪魁祸首是postId
,您正在使用它从Firebase获取数据,但是您还没有在任何地方显示它的值。当用户点击图像时,postId
不会传输到SiteViewController
。
在SiteViewController
中删除!
并将其替换为?
,放置一个将postID作为参数的初始值设定项。
var postId:String?
func initPost(forImage postId: String) {
self.postId=postId
}
在之前的新闻feed VC中,在
segue
或didSelectForRow
中(我不知道您用于转换的是什么,初始化SiteViewController
,所以当它出现时,它知道要为哪个ID检索数据。另一件需要提及的事情是,您使用的是
observe
,但没有删除观察者。编辑:这个答案是基于我不知道你的家庭风险投资是什么样子。
if segue.identifier == "SiteSegue" {
let siteVC = segue.destination as! SiteViewController
let postId = sender as! String
siteVC.postId = postId
}