I have an app that is playing up. All my data is being displayed in the black circle. I need it to be displayed in the red circle. Is it a problem in my controller class or do I need to somehow assign the tableview to this controller? I couldn't find any solutions like this online
image1
This is my code for the ViewController class:
import UIKit
import SafariServices
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private
let tableView: UITableView = {
let table = UITableView()
table.register(NewsTableViewCell.self,
forCellReuseIdentifier: NewsTableViewCell.identifier)
return table
}()
private
var viewModels = [NewsTableViewCellViewModel]()
private
var articles = [Article]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesBackButton = true
title = "News"
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
// Do any additional setup after loading the view
getTopArticles()
searchArticles()
}
func getTopArticles() {
ArticlesAPI.shared.getTopArticles {
[weak self] result in //looking at API
switch result {
case.success(let articles): // if there are results
self?.articles = articles
self?.viewModels = articles.compactMap({
NewsTableViewCellViewModel(title: $0.title, //tableview needs to be added
subtitle: $0.description ?? "No Description",
imageURL: URL(string: $0.urlToImage ?? ""))
})
// break
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case.failure(let error): //prints error if there is one
print(error)
}
}
}
func searchArticles() {
ArticlesAPI.shared.searchArticles(with: "apple") {
[weak self] result in //looking at API
switch result {
case.success(let articles): // if there are results
self?.viewModels = articles.compactMap({
NewsTableViewCellViewModel(title: $0.title, //tableview needs to be added
subtitle: $0.description ?? "No Description",
imageURL: URL(string: $0.urlToImage ?? ""))
})
//break
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case.failure(let error): //prints error if there is one
print(error)
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
}
// table
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard
let cell = tableView.dequeueReusableCell(withIdentifier: NewsTableViewCell.identifier,
for: indexPath)
as ? NewsTableViewCell
else {
fatalError()
}
cell.configure(with: viewModels[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let viewModel = viewModels[indexPath.row]
let article = articles[indexPath.row]
guard
let url = URL(string: article.url ?? "")
else {
return
}
let vc = SFSafariViewController(url: url)
present(vc, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
}
The red controller is embedded inside the black controller. The black controller is a navigation controller which provides the navigation bar for the red controller. You can type
navigationControllerinside of your view controller and you will see that it is of typeUINavigationController?, andOptional(?) since it may or may not exist (in your case it does exist because you embedded your controller in the storyboard). So don’t worry, your content is already inside the red view controller.The reason why you think it isn’t, is because you have created your
tableViewprogramatically and you gave it the size of the whole screen, so it covers up all of the other content:You can verify this using the layout inspector.
This isn’t needed because you already have a
UITableViewin your storyboard, you just need to create a reference to it in your view controller. So instead of:you need:
and you can register your cell alongside the other
tableViewsetup code inside theviewDidLoadmethod:And remove the code in your
viewDidLayoutSubviewsmethod as well, so that thetableViewdoesn’t take up all of the space.