美文网首页
大神来解释一下为什么?记录一个tableview的问题

大神来解释一下为什么?记录一个tableview的问题

作者: 小曼blog | 来源:发表于2019-01-09 20:20 被阅读32次

    首先说明,我的这个问题不具有普遍性,是一个偶然才会发生的事件。
    通常情况下,我们只需要把tableview的header和footer设置成0.01的高度就不会有问题了。如下图:


    image.png

    但是今天说的这种问题,却是不受tableview的header和footer的影响的。
    问题描述:
    1.tableview的type为grouped;
    2.使用了viewModel,且viewModel是懒加载的;
    3.使用多线程进行reloadData,且多线程中才第一次调用viewModel。

    问题截图:


    image.png image.png

    来看代码吧:
    ViewController:

    //
    //  ViewController.swift
    //  Test
    //
    //  Created by iOS on 2018/12/29.
    //  Copyright © 2018 weiman. All rights reserved.
    //
    
    import UIKit
    
    class ViewController: UIViewController {
        
        @IBOutlet weak var tableView: UITableView!
        private lazy var viewModel = ViewModel(newTableView)
    //    private var viewModel: ViewModel?
        
        private lazy var newTableView: UITableView = {
            return $0
        }( UITableView(frame: .zero, style: .grouped) )
        
        override func viewDidLoad() {
            super.viewDidLoad()
            automaticallyAdjustsScrollViewInsets = false
    //        setup()
            loadData()
        }
    
        private func setup() {
    //        let _ = viewModel
    //        viewModel = ViewModel(tableView)
            
            let frame = CGRect(x: 0,
                               y: 100,
                               width: view.frame.size.width,
                               height: view.frame.size.height - 100 - 49)
            newTableView.frame = frame
            newTableView.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
            
        }
    
    }
    
    extension ViewController {
        
        private func loadData() {
            
    //        let group = DispatchGroup()
    //
    //        group.enter()
    //        let work1 = DispatchQueue(label: "1")
    //        work1.async {
    //            print("线程1")
    //            Thread.sleep(forTimeInterval: 2)
    //            print("线程1执行完成")
    //            group.leave()
    //        }
    //
    //        group.enter()
    //        let work2 = DispatchQueue(label: "2")
    //        work2.async {
    //            print("线程2")
    //            Thread.sleep(forTimeInterval: 3)
    //            print("线程2执行完成")
    //            group.leave()
    //        }
    //
    //        group.notify(queue: .main) { [weak self] in
    //            guard let self = self else { return }
    //            let _ = self.viewModel
    //            DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: {
    //                print("reload")
    //                self.viewModel.reload()
    //            })
    //        }
            
    //        self.viewModel.reload()
            /*
             while(!isFinished) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }
    
             */
           
    //        viewModel.tableView.delegate = viewModel
    //        viewModel.tableView.dataSource = viewModel
            
            DispatchQueue.main.asyncAfter(deadline: .now()) {
                self.setup()
                self.view.addSubview(self.newTableView)
                self.newTableView.delegate = self.viewModel
                self.newTableView.dataSource = self.viewModel
                
                self.viewModel.reload()
            }
        }
    }
    
    

    ViewModel

    //
    //  ViewModel.swift
    //  Test
    //
    //  Created by iOS on 2018/12/29.
    //  Copyright © 2018 weiman. All rights reserved.
    //
    
    import UIKit
    
    class ViewModel: NSObject {
    
        let tableView: UITableView
        
        init(_ tableView: UITableView) {
            self.tableView = tableView
            super.init()
            setup()
        }
        
        private func setup() {
            
    //        tableView.delegate = self
    //        tableView.dataSource = self
            
            tableView.estimatedRowHeight = 0
            tableView.estimatedSectionFooterHeight = 0
            tableView.estimatedSectionHeaderHeight = 0
            if #available(iOS 11.0, *) {
                tableView.contentInsetAdjustmentBehavior = .never
            }
            tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
            tableView.register(Header.self, forHeaderFooterViewReuseIdentifier: "header")
            tableView.register(Footer.self, forHeaderFooterViewReuseIdentifier: "footer")
        }
        
        func reload() {
            tableView.reloadData()
        }
    }
    
    extension ViewModel: UITableViewDataSource {
        
        func numberOfSections(in tableView: UITableView) -> Int {
            return 3
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            switch section {
            case 0:     return 1
            case 1:     return 3
            case 2:     return 1
            default:    return 0
            }
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = "哈哈哈哈"
            return cell
        }
        
        func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header")
            header?.contentView.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
            return header
        }
        
        func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
            let footer  = tableView.dequeueReusableHeaderFooterView(withIdentifier: "footer")
            footer?.contentView.backgroundColor = #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1)
            return footer
        }
    }
    
    extension ViewModel: UITableViewDelegate {
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 100
        }
        
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            print("heightForHeaderInSection: \(section)")
            switch section {
            case 1, 2: return 60
            default: return 0.01
            }
        }
        
        func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
            print("heightForFooterInSection: \(section)")
            return 0.01
        }
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            print(tableView.contentOffset)
        }
    }
    
    

    把代码修改成如下这样都是没有问题的:

    方法一:把self.view.addSubview(self.newTableView)放在设置代理的后面。


    image.png

    方法二:去掉多线程

    image.png

    方法三:把设置代理的方法放在外面

    image.png

    方法四: 不使用懒加载;

    方法五:在viewdidload中,先把懒加载给初始化;

    实在想不明白为什么,还请大神出来解释一下呗,感激不尽。

    demo地址:https://github.com/weiman152/TableViewGroupedTest/tree/master

    相关文章

      网友评论

          本文标题:大神来解释一下为什么?记录一个tableview的问题

          本文链接:https://www.haomeiwen.com/subject/uckplqtx.html