简体   繁体   English

(iOS + Firebase)无法将图像从UITableViewCell传递到下一个ViewController

[英](iOS + Firebase) Unable to pass the Image to the next ViewController from a UITableViewCell

I have a UITableView where the data is coming from a Firebase RealtimeDatabase. 我有一个UITableView ,其中的数据来自Firebase RealtimeDatabase。 Once the user selects the row, the data from the row ie: Title, Description and an Image will be taken to the next ViewController. 一旦用户选择了该行,该行中的数据即标题,描述和图像将被带到下一个ViewController。

I'm able to pass the Title and Description but I'm unable to pass the Image. 我可以通过标题和说明,但不能通过图像。

Here is my code for the UITableView: 这是我的UITableView代码:

import UIKit
import Firebase

class PostTable: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var tableView:UITableView!

    var posts = [Post]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView = UITableView(frame: view.bounds, style: .plain)
        view.addSubview(tableView)

        let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
        tableView.register(cellNib, forCellReuseIdentifier: "postCell")
        var layoutGuide:UILayoutGuide!

        layoutGuide = view.safeAreaLayoutGuide

        tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
        tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true

        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        tableView.reloadData()


        observePosts()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func observePosts() {
        let postsRef = Database.database().reference().child("Data")
        print(postsRef)
        postsRef.observe(.value, with: { snapshot in
            var tempPosts = [Post]()

            for child in snapshot.children{

                if let childSnapshot = child as? DataSnapshot,
                    let dict = childSnapshot.value as? [String:Any],
                    let title = dict["title"] as? String,
                    let logoImage = dict["image"] as? String,
                    let url = URL(string:logoImage),
                    let description = dict["description"] as? String{


                    let userProfile = UserProfile(title: title, photoURL: url)
                    let post = Post(id: childSnapshot.key, title: userProfile, description: description, image: userProfile)
                    print(post)
                    tempPosts.append(post)
                }
            }

            self.posts = tempPosts
            self.tableView.reloadData()
        })
    }

    func getImage(url: String, completion: @escaping (UIImage?) -> ()) {
        URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
            if error == nil {
                completion(UIImage(data: data!))
            } else {
                completion(nil)
            }
            }.resume()
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(posts.count)
        return posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
        cell.set(post: posts[indexPath.row])
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let postsInfo = posts[indexPath.row]
        print(postsInfo)

        let Storyboard = UIStoryboard(name: "Main", bundle: nil)
        let DvC = Storyboard.instantiateViewController(withIdentifier: "PostTableDetailed") as! PostTableDetailed
        DvC.getName = postsInfo.title.title
        DvC.getDesc = postsInfo.description
//        DvC.getImg = postsInfo.title.photoURL
        self.navigationController?.pushViewController(DvC, animated: true)
    }
}

Here is the second ViewControler which has the post details: 这是第二个具有帖子详细信息的ViewControler:

import UIKit

class PostTableDetailed: UIViewController {

    var getName = String()
    var getDesc = String()

    @IBOutlet weak var Name: UILabel!
    @IBOutlet weak var Description: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        Name.text! = getName
        Description.text! = getDesc     
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

I also have a few Models (Post, UserProfile) and Services (UserService and ImageService), please let me know if that is required to break down this problem. 我也有一些模型(Post,UserProfile)和服务(UserService和ImageService),请告诉我是否可以解决此问题。

if you have the imageUrl, all you need is to pass it from PostTable to PostTableDetailed and download the image. 如果您有imageUrl,则只需将其从PostTable传递到PostTableDetailed并下载图像。

   // PostTable
       func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let postsInfo = posts[indexPath.row]
            print(postsInfo)

            let Storyboard = UIStoryboard(name: "Main", bundle: nil)
            let DvC = Storyboard.instantiateViewController(withIdentifier: "PostTableDetailed") as! PostTableDetailed
            DvC.getName = postsInfo.title.title
            DvC.getDesc = postsInfo.description
            DvC.getImg = postsInfo.photoURL
            self.navigationController?.pushViewController(DvC, animated: true)
        }

// PostTableDetailed
class PostTableDetailed: UIViewController {

    var getName = String()
    var getDesc = String()
    var imageUrl = ""

    @IBOutlet weak var Name: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var imageView: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()

        Name.text! = getName
        Description.text! = getDesc 
        updayeImage()    
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

 private func updateImage() {
        URLSession.shared.dataTask(with: URL(string: self.imageUrl)!) { data, response, error in
            if error == nil, let data = data {
                imageView.image = UIImage(data: data)
            } 
            }.resume()
    }

}

The image will be shown when the task will complete. 任务完成时将显示该图像。 so I suggest for you to add a spinner to the imageView. 因此,我建议您将微调器添加到imageView。

In PostDetail ViewController do like this 在PostDetail ViewController中这样做

import UIKit

class PostTableDetailed: UIViewController {

    var getName = String()
    var getDesc = String()
    var getImg = String()

    @IBOutlet weak var Name: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var ImageContainer: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        Name.text! = getName
        Description.text! = getDesc    
        if let image = getImage(url: getImg) { (image)
            ImageContainer.image = image 
        }

    }

    override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
    }

    func getImage(url: String, completion: @escaping (UIImage?) -> ()) {
        URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
            if error == nil {
                completion(UIImage(data: data!))
            } else {
                completion(nil)
            }
        }.resume()
    }

}

First of all, you can use this code to download the image: 首先,您可以使用以下代码下载图像:

let imageCache = NSCache<AnyObject, AnyObject>()

extension UIImageView {

func downloadImageWithUrlString(urlString: String) -> Void {

    if urlString.count == 0 {
        print("Image Url is not found")
        return
    }

    self.image = nil
    if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
        self.image = cachedImage
        return
    }

    let request = URLRequest(url: URL(string: urlString)!)
    let dataTask = URLSession.shared.dataTask(with: request) {data, response, error in
        if error != nil { return }
        DispatchQueue.main.async {
            let downloadedImage = UIImage(data: data!)
            if let image = downloadedImage {
                imageCache.setObject(image, forKey: urlString as AnyObject)
                self.image = UIImage(data: data!)
            }
        }
    }
    dataTask.resume()
}
}

Now, if you are using the model that contains Title, Description, and ImageUrlString, then simply pass the selected model object to the next viewController. 现在,如果您使用的模型包含Title,Description和ImageUrlString,则只需将所选模型对象传递给下一个viewController。

In next ViewController, just simply call the same method to download the image which you are using on first ViewController. 在下一个ViewController中,只需调用相同的方法来下载您在第一个ViewController上使用的图像。 You don't need to pass the image from VC1 to VC2 because it might be the possible image is not downloaded yet and you select a row to move on next VC. 您无需将映像从VC1传递到VC2,因为它可能尚未下载映像,并且您选择了要在下一个VC上移动的行。

So here simple thing that pass the model object and calls the image downloading method. 因此,这里传递模型对象并调用图像下载方法的简单操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 Firebase 数据从 UITableViewCell 传递给 ViewController - Pass Firebase data from UITableViewCell to ViewController iOS Swift:将数据从ViewController传递到UITableViewCell - iOS Swift: Pass data from ViewController to UITableViewCell 将来自 Firebase 数据库的数据从 UITableviewCell 传递到下一个 ViewController 未显示 - Passing data from Firebase Database from UITableviewCell to next ViewController not showing 如何将数据从Firebase iOS从TableViewController传递到另一个ViewController - How pass data from Firebase iOS from a TableViewController to another ViewController 如何将数据从UITableViewCell传递到ViewController? - How to pass data from UITableViewCell to ViewController? 如何将用户图像从Tablecell传递到Firebase上的Viewcontroller? - How to pass user image from Tablecell to Viewcontroller on firebase? 无法从父级ViewController在UITableViewCell中设置变量 - Unable to set a variable in UITableViewCell from parent ViewController 无法将从相机拍摄的图像传递到另一个ViewController - Unable to pass image taken from camera to another viewcontroller 无法将数据表单TableView传递给iOS中的ViewController - unable to pass data form tableview to viewcontroller in ios 无法将数据传递到其他ViewController iOS - Unable to pass data to other viewController ios
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM