user3407319
user3407319

Reputation: 227

UITableView not displaying prototype cells

I am trying to make an app that connects to chromecast to play a video on TV, up till now I am still trying to display the video links using two view controllers, one contains a webview that makes the user gets the video page, the other is to display all video links inferred from the first view to make the user select which video to cast from the page. I am able to get the links but the problem is it doesn't want to be displayed in the table view cells. I have tried many methods but I noticed, for some reason the UITableViewDataSource methods are not being called at all. Here is the code:

ViewController.swift:

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {
    //MARK: Outlets
    @IBOutlet weak var searchBar: UITextField!
    @IBOutlet weak var webView: UIWebView!
    @IBOutlet weak var cancelButton: UIButton!
    @IBOutlet weak var searchBarTrailingConstraint: NSLayoutConstraint!

    //MARK: Properties
    static var videoURLs: [String] = []

    //MARK: Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        cancelButton.layer.cornerRadius = 5
        cancelButton.isHidden = true
        webView.delegate = self

    }

    func webViewDidFinishLoad(_ webView: UIWebView) {
        var videoTag = ""
        var embedTag = ""
        let htmlCode = webView.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML")
        let htmlTags = htmlCode!.components(separatedBy: "\n") as [String]
        for tag in htmlTags{
            var videoURL = ""
            if tag.contains("<video") {
                videoTag = tag.substring(from: tag.range(of: "<video")!.lowerBound)
                videoTag = videoTag.substring(to: (videoTag.range(of: ">")?.upperBound)!)
                if videoTag.contains("src"){
                    videoTag = tag.substring(from: tag.range(of: "src")!.upperBound)
                    for x in videoTag.characters{
                        if x == "\""{
                            continue
                        }else if x == "="{
                            continue
                        }else if x == ">"{
                            break
                        }else{
                            videoURL.append(x)
                        }
                    }
                }
                ViewController.videoURLs.append(videoURL)
            }
            if tag.contains("<embed") {
                embedTag = tag.substring(from: tag.range(of: "<embed")!.lowerBound)
                embedTag = embedTag.substring(to: (embedTag.range(of: ">")?.upperBound)!)
                if embedTag.contains("src"){
                    embedTag = tag.substring(from: tag.range(of: "src")!.upperBound)
                    for x in embedTag.characters{
                        if x == "\""{
                            continue
                        }else if x == "="{
                            continue
                        }else if x == ">"{
                            break
                        }else{
                            videoURL.append(x)
                        }
                    }
                }
                ViewController.videoURLs.append(videoURL)
            }
        }
        NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "Done")))
    }

    //MARK: Actions
    @IBAction func cancelPressed() {
        cancelButton.isHidden = true
        searchBarTrailingConstraint.constant = 0.0
        UIView.animate(withDuration: 0.25) {
            self.view.layoutIfNeeded()
        }
        searchBar.resignFirstResponder()
    }

    @IBAction func searchBarPressed() {
        searchBarTrailingConstraint.constant = (cancelButton.frame.width + 8.0) * -1
        UIView.animate(withDuration: 0.25) {
            self.view.layoutIfNeeded()
        }
        cancelButton.isHidden = false
    }

    @IBAction func returnButtonPressed(_ sender: UITextField) {
        cancelPressed()
        if let url = URL(string: sender.text!){
            if UIApplication.shared.canOpenURL(url){
                let request = URLRequest(url: url)
                webView.loadRequest(request)
            }else{
                let googleSearchURL = URL(string: "https://www.google.com/search?client=safari&q=\(url)&ie=UTF-8&oe=UTF-8")
                let request = URLRequest(url: googleSearchURL!)
                webView.loadRequest(request)
            }
        }else{
            var searchString: [String] = []
            var searchWord = ""
            for x in (sender.text?.characters)!{
                if x == " "{
                    searchString.append(searchWord)
                    searchWord = ""
                }else{
                    searchWord.append(x)
                }
            }
            //For appending the last word not followed by a space
            if !(searchString.last == searchWord){
                searchString.append(searchWord)
            }
            var googleSearchURL = "https://www.google.com/search?client=safari&ie=UTF-8&oe=UTF-8&q="
            for element in searchString{
                googleSearchURL.append(element)
                if !(searchString.last == element){
                    googleSearchURL.append("+")
                }

            }
            let request = URLRequest(url: URL(string:googleSearchURL)!)
            webView.loadRequest(request)
        }
    }

    @IBAction func backButtonPressed(_ sender: UIButton) {
        if webView.canGoBack{
            webView.goBack()
        }
    }

    @IBAction func forwardButtonPressed(_ sender: UIButton) {
        if webView.canGoForward {
            webView.goForward()
        }
    }

}

MediaTableViewController:

import UIKit
import AVFoundation

class MediaTableViewController: UIViewController, UITableViewDataSource {

    var videoURLs: [String] = []
    var videoScreenshots: UIImage!

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(MediaTableViewController.replyToNotification), name: nil, object: nil)

        self.tableView.dataSource = self

    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("NOW!\n\n\n", indexPath.count)

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MediaTableViewCell

        cell.videoImage.image = videoScreenshot(url: videoURLs[indexPath.count])
        cell.videoURL.text = videoURLs[indexPath.count]

        return cell
    }

    @objc func replyToNotification(){
        videoURLs = ViewController.videoURLs
        ViewController.videoURLs = []
    }

    // MARK: - Table view data source

    func videoScreenshot(url: String) -> UIImage? {

        let asset = AVURLAsset(url: URL(string: url)!)
        let generator = AVAssetImageGenerator(asset: asset)
        generator.appliesPreferredTrackTransform = true

        do {
            let imageRef = try generator.copyCGImage(at: CMTime(value: asset.duration.value/2, timescale: asset.duration.timescale), actualTime: nil)
            return UIImage(cgImage: imageRef)
        }
        catch let error as NSError
        {
            print("Image generation failed with error \(error)")
            return nil
        }
    }

}

MediaTableViewCell.swift:

import UIKit

class MediaTableViewCell: UITableViewCell {

    @IBOutlet weak var videoImage: UIImageView!
    @IBOutlet weak var videoURL: UITextView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

Here is the Main.storyboard:

main.storyboard

Upvotes: 1

Views: 1221

Answers (2)

Arashk
Arashk

Reputation: 627

As I see you didn't implement tableView delegate

 override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(MediaTableViewController.replyToNotification), name: nil, object: nil)
    self.tableView.delegate = self
    self.tableView.dataSource = self

}

then add this method to your controller

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

hope this will help

Upvotes: 0

shallowThought
shallowThought

Reputation: 19602

You do not call reloadData() thus the tableView is idle.

To fix this the following to MediaTableViewController:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    tableView.reloadData()
}

Upvotes: 2

Related Questions