Swift - TableView 中的第一项在启动时被 NavBar 截断,但此后正确显示

问题描述

我的应用程序是以编程方式构建的,因此我无法访问故事板。我有一个 TabBar 作为我的 rootViewController。它有三个选项卡,第一个是 tableView。在初始启动时,tableview 中第一个项目的顶部被切断,但是如果我切换到另一个选项卡然后返回,第一个项目会正确显示在导航栏下方,并带有一些填充。对此的一种解决方案是简单地将导航栏的 .isTransluscent 设置为 true,但颜色已关闭。另一个是设置 tableView 的 UIEdgeInsets 及其滚动指示器,但是我担心这是一个创可贴的解决方案,当我转到另一个选项卡然后返回时,它实际上会增加额外的填充。我在下面发布了我的代码,想知道它是否与我的加载 VC 或我的自定义 tableViewCell 有任何关系。启动时,如果我在 ArticleVC 出现之前切换到另一个选项卡并且 Loading VC 被解除,我会收到错误“加载 VC 的开始/结束外观转换的调用不平衡”...

// Loading VC

import UIKit

class LoadingVC: UIViewController {

var loadingLabel: UILabel = {
    let loadingLabel = UILabel()
    loadingLabel.text = "Loading articles..."
    loadingLabel.textAlignment = .center
    loadingLabel.translatesAutoresizingMaskIntoConstraints = false
    loadingLabel.font = .systemFont(ofSize: 18,weight: .heavy)
    loadingLabel.backgroundColor = .systemBackground
    return loadingLabel
}()

var loadingActivityIndicator: UIActivityIndicatorView = {
    let indicator = UIActivityIndicatorView()
    
    indicator.style = .large
    indicator.startAnimating()

    indicator.translatesAutoresizingMaskIntoConstraints = false
    indicator.backgroundColor = .systemBackground
    return indicator
}()

var blurEffectView: UIVisualEffectView = {
    let blurEffect = UIBlurEffect(style: .regular)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    
    blurEffectView.alpha = 0.8
    
    blurEffectView.translatesAutoresizingMaskIntoConstraints = false
    blurEffectView.backgroundColor = .systemBackground
    return blurEffectView
}()


override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .systemBackground
    view.addSubview(loadingLabel)
    view.addSubview(blurEffectView)
    blurEffectView.frame = view.bounds
    
    view.addSubview(loadingActivityIndicator)
    loadingActivityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    loadingActivityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    
    view.addSubview(loadingLabel)
    loadingLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    loadingLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor,constant: 50).isActive = true
    
    
}


import SafariServices
import UIKit

class ArticlesTVC: UITableViewController,SFSafariViewControllerDelegate {

var articles = [Article]()

let cellId = "articleTableViewCell"
let loadingVC = LoadingVC()

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    
    tableView.contentInset = UIEdgeInsets.init(top: 40,left: 0,bottom: 0,right: 0)
    tableView.scrollIndicatorInsets = UIEdgeInsets.init(top: 40,right: 0)
}
override func viewDidLoad() {
    super.viewDidLoad()

    registerarticleCell()
    fetchArticles()
    
    loadingVC.modalPresentationStyle = .currentContext
    loadingVC.modalTransitionStyle = .crossdissolve
    self.definesPresentationContext = true
    
    dispatchQueue.main.async {
        self.present(self.loadingVC,animated: true)
    }
    
    self.title = "Top Stories"
    navigationController?.navigationBar.prefersLargeTitles = false
    navigationController?.navigationBar.isTranslucent = false
    navigationController?.navigationBar.barTintColor = .systemBackground

    self.refreshControl = UIRefreshControl()
    refreshControl?.addTarget(self,action: #selector(fetchArticles),for: .valueChanged)
    refreshControl?.attributedTitle = NSAttributedString(string: "Updating...")
    refreshControl?.tintColor = .systemRed

    tableView.separatorStyle = .none
    tableView.backgroundColor = .systemBackground
    

}

func registerarticleCell() { tableView.register(ArticleTableViewCell.self,forCellReuseIdentifier: cellId) }

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

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

override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellId,for: indexPath) as! ArticleTableViewCell
    let article = articles[indexPath.row]
    cell.set(article: article)
    return cell
}

override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    let article = articles[indexPath.row]
    loadArticle(articleURL: article.url!)
}

override func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat { return 400 }

func loadArticle(articleURL: String) {
    if let url = URL(string: articleURL) {
        let vc = SFSafariViewController(url: url)
        vc.delegate = self
        present(vc,animated: true)
    }
}

func safariViewControllerDidFinish(_ controller: SFSafariViewController) { dismiss(animated: true) }

@objc func fetchArticles() {

let baseURL = ""
    
    guard let url = URL(string: "\(baseURL)") else { print("url Failed"); return }

    let session = URLSession(configuration: .default)

     session.dataTask(with: url) { data,response,error in

        if error != nil {
            print(error ?? "error fetching articles")
            return
        }

        if let safeData = data {
            self.parseJSON(data: safeData)
        }

    }.resume()
}

func parseJSON(data: Data) {
    let decoder = JSONDecoder()

    do {
        self.articles.removeAll()
        let decodedData = try decoder.decode(NewsData.self,from: data)
        let newsArticles = decodedData.news
        for item in newsArticles {
            let title = item.title
            let description = item.description
            let url = item.url
            let image = item.image
            let published = item.published

            let article = Article(title: title,description: description,url: url,image: image,published: published)
            self.articles.append(article)
            
            dispatchQueue.main.async {
                self.loadingVC.dismiss(animated: true)
                self.refreshControl?.endRefreshing()
                self.tableView.reloadData()
            }
        }
        print("articles loaded successfully")
    } catch {
        print("Error decoding: \(error)")
    }
}

}

 // Custom TableView Cell
import UIKit

class ArticleTableViewCell: UITableViewCell {

var articleImageView = UIImageView()

override init(style: UITableViewCell.CellStyle,reuseIdentifier: String?) {
    super.init(style: style,reuseIdentifier: reuseIdentifier)

    addSubview(articleImageView)
    configureImageView()
}

required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }

func configureImageView() {
    articleImageView.translatesAutoresizingMaskIntoConstraints = false
    articleImageView.topAnchor.constraint(equalTo: self.topAnchor,constant: 5).isActive = true
    articleImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor,constant: -15).isActive = true
    articleImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor,constant: 20).isActive = true
    articleImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor,constant: -20).isActive = true
    
    articleImageView.contentMode = .scaleAspectFill
    articleImageView.layer.cornerRadius = 20
    articleImageView.clipsToBounds = true
}

}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)