You're calling present() from a view controller (TutorialsTableView: UIViewController) that’s not actually on screen.
Just pass a real UIViewController :
class TutorialsTableView: NSObject, UITableViewDataSource, UITableViewDelegate {
weak var viewController: UIViewController? // !NEW LINE!
class TutorialsViewController: UIViewController, UIScrollViewDelegate {
let tutorialsClassRef = TutorialsTableView()
@IBOutlet weak var tutorialsTable:TableViewAdjustedHeight! {
didSet {
self.tutorialsTable.delegate = tutorialsClassRef
self.tutorialsTable.dataSource = tutorialsClassRef
self.tutorialsTable.viewController = self // !NEW LINE!
}
}
And call present on that viewController property:
let popupVC = mainStoryboard.instantiateViewController(withIdentifier: tutorials.name)
popupVC.modalPresentationStyle = .popover
viewController?.present(popupVC, animated: true, completion: nil) // changed code
Also, you might notice I changed TutorialsTableView from a UIViewController to NSObject. Why?
Because this class is only used to separate out the table’s data source and delegate logic — it’s not meant to be shown on screen. We're just keeping things clean and modular.
As for NSObject, it's required since UIKit protocols like UITableViewDataSource and UITableViewDelegate inherit from NSObjectProtocol. So any class conforming to them needs to inherit from NSObject.