Firebase - iOs:如何将数据从Tableview传递到DetailsView?

时间:2017-02-06 16:24:37

标签: ios swift firebase firebase-realtime-database

我有一个控制器“Feed”,它通过Firebase中的表格(标题和图片)列出多个帖子。

enter image description here

触摸按钮时,它会显示“Feed Details”控制器,我希望显示之前点击的帖子(父级)中的数据(标题图像和标题)。 (见截图2)

enter image description here enter image description here

目前On Click,我刚收到静态信息,没有任何信息是从Firebase获取的。但是,它们都在主屏幕中被正确调用。所以问题是当它转向“DetailsController”

如何从先前点击的项目中获取详细信息?

目前这是我的饲料控制器:

//
//  Feed.swift
//  MobileAppDemo
//
//  Created by Mikko Hilpinen on 31.10.2016.
//  Copyright © 2016 Mikkomario. All rights reserved.
//

import UIKit
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
import SwiftKeychainWrapper
import SwiftyJSON

class FeedVC: UIViewController, UITableViewDataSource,     UIImagePickerControllerDelegate, UINavigationControllerDelegate
{
@IBOutlet weak var addImageView: UIImageView!
@IBOutlet weak var feedTableView: UITableView!
@IBOutlet weak var titleInputView: InputTextView!
@IBOutlet weak var linkbutton: UIButton!

@IBOutlet weak var captionInputView: InputTextView!


private var posts = [Post]()
private var imagePicker = UIImagePickerController()
private var imageSelected = false

private var readPosts: ObserveTask?

override func viewDidLoad()
{
    super.viewDidLoad()

    imagePicker.delegate = self
    imagePicker.allowsEditing = true

    feedTableView.dataSource = self

    feedTableView.rowHeight = UITableViewAutomaticDimension
    feedTableView.estimatedRowHeight = 320

    readPosts = Post.observeList(from: Post.parentReference.queryOrdered(byChild: Post.PROPERTY_CREATED))
    {
        posts in

        self.posts = posts.reversed()
        self.feedTableView.reloadData()
    }



}

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


// here you need to add
{


    if let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as? MessageCell
    {

        let post = posts[indexPath.row]
        cell.configureCell(tableView: tableView, post: post)
        cell.linkbutton.tag = indexPath.row
        cell.linkbutton.addTarget(self, action: #selector(FeedVC.toFeedDetailAction(_:)), for: .touchUpInside)
        return cell

    }
    else
    {
        fatalError()
    }
}

func toFeedDetailAction(_ sender: UIButton) {

    let FeedDetailsController = self.storyboard?.instantiateViewController(withIdentifier: "FeedDetailsController") as! FeedDetailsController
    FeedDetailsController.post = posts[sender.tag]
    self.navigationController?.pushViewController(FeedDetailsController, animated: true)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage
    {
        addImageView.image = image

        imageSelected = true
    }
    picker.dismiss(animated: true, completion: nil)
}

@IBAction func selectImagePressed(_ sender: AnyObject)
{
    present(imagePicker, animated: true, completion: nil)
}

@IBAction func postButtonPressed(_ sender: AnyObject)
{
    guard let caption = captionInputView.text, !caption.isEmpty else
    {
        // TODO: Inform the user
        print("POST: Caption must be entered")
        return
    }

    guard let title = titleInputView.text, !title.isEmpty else
    {
        // TODO: Inform the user
        print("POST: title must be entered")
        return
    }

    guard let image = addImageView.image, imageSelected else
    {
        print("POST: Image must be selected")
        return
    }

    guard let currentUserId = User.currentUserId else
    {
        print("POST: Can't post before logging in")
        return
    }

    imageSelected = false
    addImageView.image = UIImage(named: "add-image")
    captionInputView.text = nil
    titleInputView.text = nil

    // Uploads the image
    if let imageData = UIImageJPEGRepresentation(image, 0.2)
    {
        let imageUid = NSUUID().uuidString
        let metadata = FIRStorageMetadata()
        metadata.contentType = "image/jpeg"

        Storage.REF_POST_IMAGES.child(imageUid).put(imageData, metadata: metadata)
        {
            (metadata, error) in

            if let error = error
            {
                print("STORAGE: Failed to upload image to storage \(error)")
            }

            if let downloadURL = metadata?.downloadURL()?.absoluteString
            {
                // Caches the image for faster display
                Storage.imageCache.setObject(image, forKey: downloadURL as NSString)

                print("STORAGE: Successfully uploaded image to storage")
                _ = Post.post(caption: caption, title: title, imageUrl: downloadURL, creatorId: currentUserId)
            }
        }
    }
}

@IBAction func signOutButtonPressed(_ sender: AnyObject)
{
    // Doesn't listen to posts anymore
    readPosts?.stop()

    try! FIRAuth.auth()?.signOut()
    User.currentUserId = nil
    dismiss(animated: true, completion: nil)
}
}

和我的Feed详情:

//
//  FeedDetails.swift
//  MobileAppDemo
//
//  Created by Mikko Hilpinen on 31.10.2016.
//  Copyright © 2016 Mikkomario. All rights reserved.
//

import UIKit
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
import SwiftKeychainWrapper
import SwiftyJSON

class FeedDetailsController: UIViewController, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate
{
@IBOutlet weak var addImageView: UIImageView!
@IBOutlet weak var feedTableView: UITableView!
@IBOutlet weak var titleInputView: InputTextView!
@IBOutlet weak var linkbutton: UIButton!

@IBOutlet weak var captionInputView: InputTextView!

var post: Post!

private var posts = [Post]()
private var imagePicker = UIImagePickerController()
private var imageSelected = false

private var readPosts: ObserveTask?

override func viewDidLoad()
{
    super.viewDidLoad()

    imagePicker.delegate = self
    imagePicker.allowsEditing = true


    readPosts = Post.observeList(from: Post.parentReference.queryOrdered(byChild: Post.PROPERTY_CREATED))
    {
        posts in

        self.posts = posts.reversed()
    }



}

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


    // here you need to add
{


    if let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as? MessageCell
    {

        let post = posts[indexPath.row]
        cell.configureCell(tableView: tableView, post: post)
        cell.linkbutton.tag = indexPath.row
        cell.linkbutton.addTarget(self, action: #selector(FeedVC.toFeedDetailAction(_:)), for: .touchUpInside)
        return cell

    }
    else
    {
        fatalError()
    }
}


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage
    {
        addImageView.image = image

        imageSelected = true
    }
    picker.dismiss(animated: true, completion: nil)
}

@IBAction func selectImagePressed(_ sender: AnyObject)
{
    present(imagePicker, animated: true, completion: nil)
}

@IBAction func postButtonPressed(_ sender: AnyObject)
{
    guard let caption = captionInputView.text, !caption.isEmpty else
    {
        // TODO: Inform the user
        print("POST: Caption must be entered")
        return
    }

    guard let title = titleInputView.text, !title.isEmpty else
    {
        // TODO: Inform the user
        print("POST: title must be entered")
        return
    }

    guard let image = addImageView.image, imageSelected else
    {
        print("POST: Image must be selected")
        return
    }

    guard let currentUserId = User.currentUserId else
    {
        print("POST: Can't post before logging in")
        return
    }

    imageSelected = false
    addImageView.image = UIImage(named: "add-image")
    captionInputView.text = nil
    titleInputView.text = nil

    // Uploads the image
    if let imageData = UIImageJPEGRepresentation(image, 0.2)
    {
        let imageUid = NSUUID().uuidString
        let metadata = FIRStorageMetadata()
        metadata.contentType = "image/jpeg"

        Storage.REF_POST_IMAGES.child(imageUid).put(imageData, metadata: metadata)
        {
            (metadata, error) in

            if let error = error
            {
                print("STORAGE: Failed to upload image to storage \(error)")
            }

            if let downloadURL = metadata?.downloadURL()?.absoluteString
            {
                // Caches the image for faster display
                Storage.imageCache.setObject(image, forKey: downloadURL as NSString)

                print("STORAGE: Successfully uploaded image to storage")
                _ = Post.post(caption: caption, title: title, imageUrl: downloadURL, creatorId: currentUserId)
            }
        }
    }
}

@IBAction func signOutButtonPressed(_ sender: AnyObject)
{
    // Doesn't listen to posts anymore
    readPosts?.stop()

    try! FIRAuth.auth()?.signOut()
    User.currentUserId = nil
    dismiss(animated: true, completion: nil)
}
}

2 个答案:

答案 0 :(得分:0)

您需要在表格视图中实现prepare(for:sender:)UITableViewDelegate方法)并将需要显示的数据添加到那里的详细视图控制器。

答案 1 :(得分:0)

好的,我尝试使用你的代码,但有很多缺少的元素,它返回错误,所以我不知道这是否会编译,但应该这样做。

首先:

我假设两个类中的private var posts = [Post]()保持相同的帖子值

<强>第二

您需要将UITableViewDelegate添加到您的超类

class FeedVC: UIViewController, UITableViewDataSource, UITableViewDelegate, ...

<强>第三

FeedVC中添加以下内容:

private var selectedIndexPath: Int = 0

这在您的FeedDetailsController

var selectedIndexPath: Int = 0 // cannot be private to get accessed from FeedVC

和FeedVC中的Delegate函数:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        selectedIndexPath = indexPath.row
    }

和FeedVC中的segue准备:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let newViewController = segue.destination as! FeedDetailsController

        newViewController.selectedIndexPath = selectedIndexPath
    }

最后,您现在可以使用selectedIndexPath中的posts来获取所选帖子

let post = posts[selectedIndexPath]

希望这有帮助!