This is the tableviewController which supposed to show image in each row but it does not. When I run the application on simulator it starts and displays the table view with titles and subtitles but images. I also attach the screenshots of simulator with some prints and of the structure of the database.
import UIKit
import AVKit
import AVFoundation
import FirebaseFirestore
import Combine
class ListOfVideoLessonsTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let pinchGesture = UIPinchGestureRecognizer()
private var viewModel = VideosViewModel()
private var cancellable: AnyCancellable?
var player = AVPlayer()
var playerViewController = AVPlayerViewController()
@IBOutlet var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel.fetchData()
self.title = "Video Lessons"
table.delegate = self
table.dataSource = self
cancellable = viewModel.$videos.sink { _ in
DispatchQueue.main.async{
self.table.reloadData()
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("videos count = ", viewModel.videos.count)
return viewModel.videos.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let video = viewModel.videos[indexPath.row]
tableView.tableFooterView = UIView()
cell.textLabel?.text = video.name
cell.detailTextLabel?.text = video.lessonName
cell.accessoryType = .disclosureIndicator
let image = UIImage(named: video.imageName)
cell.imageView?.image = image
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
cell.selectedBackgroundView = backgroundView
cell.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
cell.detailTextLabel?.font = UIFont(name: "Helvetica", size: 12)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
playVideo(at: indexPath)
}
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.contentView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
cell.textLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
cell.detailTextLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
}
}
func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.contentView.backgroundColor = nil
}
}
func playVideo(at indexPath: IndexPath){
let selectedVideo = viewModel.videos[indexPath.row]
let videoURL = URL(string: selectedVideo.fileURL)
player = AVPlayer(url: videoURL!)
playerViewController.player = player
self.present(playerViewController, animated: true, completion: {
self.playerViewController.player?.play()
})
}
}
This is the viewModel which I believe should download images and pass to the tableview cells.
import Foundation
import FirebaseFirestore
class VideosViewModel: ObservableObject {
@Published var videos = [Video]()
private var db = Firestore.firestore()
func fetchData() {
db.collection("videos").addSnapshotListener { [self] (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No Documents")
return
}
self.videos = documents.map { (queryDocumentSnapshot) -> Video in
let data = queryDocumentSnapshot.data()
let name = data["name"] as? String ?? ""
let imageName = data["imageName"] as? String ?? ""
let lessonName = data["lessonName"] as? String ?? ""
let fileURL = data["fileURL"] as? String ?? ""
print(data)
return Video(name: name , imageName: imageName , lessonName: lessonName, fileURL: fileURL )
}
}
}
}
And this the struct of the video
import Foundation
struct Video {
var name: String
var imageName: String
var lessonName: String
var fileURL: String
}
CodePudding user response:
Does an image with that 'video.imageName' exist within the app?
let image = UIImage(named: video.imageName)
cell.imageView?.image = image
you should be download from firebase storage.
use to
guard let url = URL(string: video.imageName) else {return}
URLSession.shared.dataTask(with: URL, completionHandler: (Data?, URLResponse?, Error?) -> Void)
CodePudding user response:
the first answer is one option however you will encounter the frozen screen while scrolling the UITableView. if you want to void that. Then you can use SDWebImage SDK
import UIKit
import SDWebImage
class ListOfVideoLessonsTableViewController {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let video = viewModel.videos[indexPath.row]
tableView.tableFooterView = UIView()
cell.textLabel?.text = video.name
cell.detailTextLabel?.text = video.lessonName
cell.accessoryType = .disclosureIndicator
let image = UIImage(named: video.imageName)
cell.imageView?.sd_imageIndicator = SDWebImageActivityIndicator.gray
cell.sd_setImage(with: URL(string: stringWithoutWhitespace), placeholderImage: UIImage())
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
cell.selectedBackgroundView = backgroundView
cell.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
cell.detailTextLabel?.font = UIFont(name: "Helvetica", size: 12)
return cell
}
}