[英](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.