UITableViewController 表格视图单元仅在调试时显示

问题描述 投票:0回答:1

当应用程序处于调试状态时,Tableview 单元格可见,但当尝试终止应用程序并尝试重新打开应用程序时,单元格不可见。

方法(我在我的应用程序中使用的):

lazy var contactPickerScene: ContactTabelViewController = {
     guard let contactPickerScene = self.storyboard?.instantiateViewController(identifier: "ContactTabelViewController") as? ContactTabelViewController else {
        return ContactTabelViewController()
       }
      return contactPickerScene
      }()
contactPickerScene.contactDelegate = self
contactPickerScene.multiSelectEnabled = true
contactPickerScene.subtitleCellValue = .email
contactPickerScene.view.frame = self.contactListView.bounds
self.addChild(contactPickerScene)
self.contactListView.addSubview(contactPickerScene.view)
contactPickerScene.didMove(toParent: self)
public class ContactTabelViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {

      ---------------------------
      public override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
        
        self.title = "Contacts"

        self.tableView.dataSource = self
        self.tableView.delegate = self
        
        inititlizeBarButtons()
        initializeSearchBar()
        registerContactCell()
        fetchContacts()
    }
    ---------------------------
}
// MARK: - Contact Operations
extension ContactTabelViewController {
    func fetchContacts() {
        DispatchQueue.global().async {
            self.getContacts( {(contacts, error) in
                if (error == nil) {
                    DispatchQueue.main.async(execute: {
//                        self.tableView.dataSource = self
//                        self.tableView.delegate = self
                        self.contactsList = contacts
                        self.tableView.reloadData()
                    })
                }
            })
        }
    }
    
    func getContacts(_ completion:  @escaping ContactsHandler) {
        if contactsStore == nil {
            contactsStore = CNContactStore()
        }
        let error = NSError(domain: "ContactPickerErrorDomain", code: 1, userInfo: [NSLocalizedDescriptionKey: "No Contacts Access"])
        
        switch CNContactStore.authorizationStatus(for: CNEntityType.contacts) {
        case CNAuthorizationStatus.denied, CNAuthorizationStatus.restricted:
            DispatchQueue.main.async {
                if self.contactsList.isEmpty {
                    self.tableView.isScrollEnabled = false
                    self.resultSearchController.searchBar.isHidden = true
                    self.tableView.setEmptyMessage("We could not fetch your contacts. Please allow contacts permission.")
                }
            }
        case CNAuthorizationStatus.notDetermined:
            contactsStore?.requestAccess(for: CNEntityType.contacts, completionHandler: { (granted, error) -> Void in
                if  (!granted ){
                    DispatchQueue.main.async(execute: { () -> Void in
                        completion([], error! as NSError?)
                    })
                }
                else{
                    DispatchQueue.global().async {
                        self.orderedContacts = [String: [CNContact]]()
                        self.getContacts(completion)
                    }
                }
            })
        case  CNAuthorizationStatus.authorized:
            var contactsArray = [CNContact]()
            let contactFetchRequest = CNContactFetchRequest(keysToFetch:[CNContactVCardSerialization.descriptorForRequiredKeys()])
            contactFetchRequest.sortOrder = CNContactSortOrder.givenName
            do {
                try contactsStore?.enumerateContacts(with: contactFetchRequest, usingBlock: { (contact, stop) -> Void in
                    var key: String = "#"
                    if let firstLetter = contact.givenName[0..<1] , firstLetter.containsAlphabets() {
                        key = firstLetter.uppercased()
                    }
                    var contacts = [CNContact]()
                    if let segregatedContact = self.orderedContacts[key] {
                        contacts = segregatedContact
                    }
                    if(contactsArray.count == 0){
                        if !Constant.boolIsSubscribe {
                            contacts.append(contact)
                        }
                    }
                    contacts.append(contact)
                    self.orderedContacts[key] = contacts
                    contactsArray.append(contact)
                })
                self.sortedContactKeys = Array(self.orderedContacts.keys).sorted(by: <)
                if self.sortedContactKeys.first == "#" {
                    self.sortedContactKeys.removeFirst()
                    self.sortedContactKeys.append("#")
                }
                completion(contactsArray, nil)
            }
            //Catching exception as enumerateContactsWithFetchRequest can throw errors
            catch let error as NSError {
                print(error.localizedDescription)
            }
        @unknown default:
            break
        }
    }
}

调试时:

应用程序被杀死后:

我希望得到与调试时相同的结果。当应用程序从调试状态终止后运行时,单元格需要加载负载。

在这个问题中,我已经花了 2 天时间,还创建了单独的 UItableviewcontroller 但得到了相同的结果。

XCode 版本 15.0 雨燕5.0 iOS 17.0 MacOS 索诺玛

我目前正在使用这个环境。

不同场景下再次出现相同问题

我在同一个项目和历史页面的

UITableView
中再次发现了同样的问题,当设备附加到系统和应用程序正在运行时,向我显示一些历史记录,但每当我杀死应用程序并运行它时,它都会显示空白的表格视图。

连接到设备并运行时记录

09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 146 ==> GetLoadFileFromDocumentDict()
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 340.0 ==> 262 ==> tableView(_:heightForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 75.0 ==> 266 ==> tableView(_:heightForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 181 ==> tableView(_:cellForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 340.0 ==> 262 ==> tableView(_:heightForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 181 ==> tableView(_:cellForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 75.0 ==> 266 ==> tableView(_:heightForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 340.0 ==> 262 ==> tableView(_:heightForRowAt:)
09:16:36: <SharingApp.HistoryViewController: 0x11a4ac770> ==> 75.0 ==> 266 ==> tableView(_:heightForRowAt:)

未连接到设备并运行时记录

09:17:49: <SharingApp.HistoryViewController: 0x119563620> ==> 146 ==> GetLoadFileFromDocumentDict()
09:17:49: <SharingApp.HistoryViewController: 0x119563620> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:17:49: <SharingApp.HistoryViewController: 0x119563620> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:17:50: <SharingApp.HistoryViewController: 0x119563620> ==> 340.0 ==> 262 ==> tableView(_:heightForRowAt:)
09:17:50: <SharingApp.HistoryViewController: 0x119563620> ==> 75.0 ==> 266 ==> tableView(_:heightForRowAt:)
09:17:50: <SharingApp.HistoryViewController: 0x119563620> ==> 2 ==> 171 ==> tableView(_:numberOfRowsInSection:)
09:17:50: <SharingApp.HistoryViewController: 0x119563620> ==> 340.0 ==> 262 ==> tableView(_:heightForRowAt:)
09:17:50: <SharingApp.HistoryViewController: 0x119563620> ==> 75.0 ==> 266 ==> tableView(_:heightForRowAt:)

我不知道为什么

cellForRowAt
没有接到电话。

HistoryViewcontroller.Swift

import UIKit
import Photos
import QuickLook
import Kingfisher
import GoogleMobileAds

struct History : Codable {
    let name: String?
    let data: Data?
    let date: Date?
    let size: Int?
    let docType: URLType
}

class HistoryViewController: UIViewController {
    
    @IBOutlet weak var tblHistory: UITableView!
    
    var rightBarButton : UIBarButtonItem!
    var arraySplitArray = [URL]()
    lazy var previewItem = NSURL()
    var arryValue = [URL]()
   
    var imageLocal = [UIImage]()
    var selectedIndexPath = [IndexPath]()
    var boolIsNativeAdHide : Bool = false
    
    enum Errors : Error {
        case error1(str: String?)
        case error2
        case error3
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        rightBarButton = UIBarButtonItem(title: "Delete All", style: .plain, target: self, action: #selector(didTapSelectButton(sender:)))
        navigationItem.rightBarButtonItem = rightBarButton
        
        isSmallNativeAd = false
        tblHistory.register(UINib(nibName: "HistoryTableViewCell2", bundle: nil), forCellReuseIdentifier: "HistoryTableViewCell2")
        tblHistory.register(UINib(nibName: "NativeAdCell", bundle: nil), forCellReuseIdentifier: "NativeAdCell")
        tblHistory.dataSource = self
        tblHistory.delegate = self
        
        self.GetLoadFileFromDocumentDict()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.title = "History"
    }

    @objc
    func didTapSelectButton(sender: AnyObject){
        let refreshAlert = UIAlertController(title: "Confirmation", message: "Are you sure you want to delete history?", preferredStyle: UIAlertController.Style.alert)

        refreshAlert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action: UIAlertAction!) in
            self.CleanHistory()
        }))

        refreshAlert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (action: UIAlertAction!) in
              print("Handle Cancel Logic here")
        }))
        present(refreshAlert, animated: true, completion: nil)
    }
    
    func CleanHistory(){
        let fileManager = FileManager.default
        let myDocuments = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
        let folderURL = myDocuments.appendingPathComponent(Constant.strFolderName)
        guard let filePaths = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) else { return }
        for filePath in filePaths {
            try? fileManager.removeItem(at: filePath)
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + 1){
            // create the alert
            let alert = UIAlertController(title: "Information", message: "History Deleted Successfully.", preferredStyle: UIAlertController.Style.alert)
            
            // add an action (button)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
            
            // show the alert
            self.present(alert, animated: true, completion: nil)
           
        }
        self.GetLoadFileFromDocumentDict()
    }
   
    func GetLoadFileFromDocumentDict() {
        self.arraySplitArray.removeAll()
        self.arryValue.removeAll()
        
        if let arrUrls = FileManager.allRecordedData() {
            arryValue = arrUrls.filter({ url in
                if url.lastPathComponent.contains("png") ||
                    url.lastPathComponent.contains("jpg") ||
                    url.lastPathComponent.contains("gif") ||
                    url.lastPathComponent.contains("tif") ||
                    url.lastPathComponent.contains("JPG") ||
                    url.lastPathComponent.contains("PNG") ||
                    url.lastPathComponent.contains("HEIC") ||
                    url.lastPathComponent.contains("WEBM") ||
                    url.lastPathComponent.contains("MPG") ||
                    url.lastPathComponent.contains("MPEG") ||
                    url.lastPathComponent.contains("MPE") ||
                    url.lastPathComponent.contains("MP4") ||
                    url.lastPathComponent.contains("M4P") ||
                    url.lastPathComponent.contains("M4V") ||
                    url.lastPathComponent.contains("AVI") ||
                    url.lastPathComponent.contains("WMV") ||
                    url.lastPathComponent.contains("MOV") ||
                    url.lastPathComponent.contains("pdf") ||
                    url.lastPathComponent.contains("vcf") ||
                    url.lastPathComponent.contains("m4a") {
                    return true
                }else {
                    return false
                }
            })
            for fileURL in arryValue {
                if(fileURL.pathExtension != ""){
                    arraySplitArray.append(fileURL)
                }
            }
            if arraySplitArray.count > 0 {
                if !Constant.boolIsSubscribe {
                    arraySplitArray.insert(URL(string: "AD")!, at: 0)
                }
                rightBarButton.isEnabled = true
            }else{
                rightBarButton.isEnabled = false
            }
            RBLogger.log("\(self) ==> \(#line) ==> \(#function)")
            self.tblHistory.reloadData()
        }
    }

    func deleteData(at indexPath: IndexPath) {
        print(indexPath.row)
        RemoveFileFromDocumentDictionary(indexPath: indexPath)
    }
    
    func RemoveFileFromDocumentDictionary(indexPath : IndexPath) {
        let fileManager = FileManager.default
        do {
            try fileManager.removeItem(at:arraySplitArray[indexPath.row])
            arraySplitArray.remove(at: indexPath.row)
            self.tblHistory.reloadData()
        } catch {
            print(error)
        }
    }
}

//MARK:- Tableview Methods
extension HistoryViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        RBLogger.log("\(self) ==> \(arraySplitArray.count) ==> \(#line) ==> \(#function)")
        if arraySplitArray.isEmpty {
            tblHistory.setEmptyView(image: UIImage(named: "noData")!, title: "", message: "")
        }else {
            tblHistory.restoreView()
        }
        return arraySplitArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        RBLogger.log("\(self) ==> \(#line) ==> \(#function)")
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            let nativeAdCell = tableView.dequeueReusableCell(withIdentifier: "NativeAdCell") as! NativeAdCell
            if !boolIsNativeAdHide {
                loadNativeAd(view: nativeAdCell.adView, isSmallNativeAd: isSmallNativeAd) {[weak self] isLoad in
                    DispatchQueue.main.async {
                        if !isLoad {
                            self?.boolIsNativeAdHide = true
                            self?.tblHistory.reloadRows(at: [IndexPath(row: indexPath.row, section: indexPath.section)], with: .none)
                        }else {
                            print("Ad already load.")
                        }
                    }
                }
            }
            nativeAdCell.selectionStyle = .none
            return nativeAdCell
        }else {
            guard let cell : HistoryTableViewCell2 = tableView.dequeueReusableCell(withIdentifier: "HistoryTableViewCell2") as? HistoryTableViewCell2 else {
                return UITableViewCell()
            }
            do {
                let checkVideoOrImage = self.checkURLType(inputURL: arraySplitArray[indexPath.row])
                if checkVideoOrImage == "Image" {
                    let data = try Data(contentsOf: self.arraySplitArray[indexPath.row])
                    DispatchQueue.main.async {
                        cell.imgThumb.image = UIImage(data: data)
                    }
                }else if checkVideoOrImage == "Video"{
                    cell.imgThumb.image = self.generateThumbnail(path: arraySplitArray[indexPath.row])
                    
                }else if (arraySplitArray[indexPath.row].pathExtension.lowercased() == "pdf"){
                    cell.imgThumb.image = UIImage.init(named: "pdf")
                }else if (arraySplitArray[indexPath.row].pathExtension.lowercased() == "vcf"){
                    cell.imgThumb.image = UIImage.init(named: "vcf")
                }else if (arraySplitArray[indexPath.row].pathExtension.lowercased() == "m4a"){
                    cell.imgThumb.image = UIImage.init(named: "musical")
                }else {
                    cell.imgThumb.image = UIImage.init(named: "document")
                }
                
                cell.lblName.text = arraySplitArray[indexPath.row].lastPathComponent
                let resourceValues = try arraySplitArray[indexPath.row].resourceValues(forKeys: [.fileSizeKey])
                let fileSize = resourceValues.fileSize!
                cell.lblSize.text = ByteCountFormatter().string(fromByteCount: Int64(fileSize))
            } catch { print(error) }
            
            let attributes = try? FileManager.default.attributesOfItem(atPath: arraySplitArray[indexPath.row].path)
            if let date = attributes?[.modificationDate] {
                print("File Modification date is %@", date)
                let dateFormatter = DateFormatter()
                let tempLocale = dateFormatter.locale
                dateFormatter.locale = Locale(identifier: "en_US_POSIX")
                dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
                dateFormatter.dateFormat = "dd-MM-yyyy"
                dateFormatter.locale = tempLocale
                let dateString = dateFormatter.string(from: date as! Date)
                cell.lblDate.text = dateString
            }
            
            cell.btnViewClick = {(_ aCell: HistoryTableViewCell2) -> Void in
                DispatchQueue.main.async {
                    self.previewItem = self.arraySplitArray[indexPath.row] as NSURL
                    let quickLookController = QLPreviewController()
                    quickLookController.dataSource = self
                    self.present(quickLookController, animated: true, completion: nil)
                }
            }
            cell.selectionStyle = .none
            return cell
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            if boolIsNativeAdHide {
                RBLogger.log("\(self) ==> 0.0 ==> \(#line) ==> \(#function)")
                return 0.0
            }else{
                RBLogger.log("\(self) ==> \(nativeAdHeight() + 40.0) ==> \(#line) ==> \(#function)")
                return nativeAdHeight() + 40.0
            }
        }else {
            RBLogger.log("\(self) ==> 75.0 ==> \(#line) ==> \(#function)")
            return 75.0
        }
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            return
        }
        if(tblHistory.isEditing){
            selectedIndexPath.append(indexPath)
            print(indexPath.row)
        }
    }
    
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            return
        }
        if(tblHistory.isEditing){
            selectedIndexPath.remove(at: indexPath.row)
            print(indexPath.row)
        }
    }
    
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            return nil
        }
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {  (contextualAction, view, boolValue) in
            self.deleteData(at: indexPath)
        }
        let swipeActions = UISwipeActionsConfiguration(actions: [deleteAction])
        
        return swipeActions
    }
    
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
}

extension HistoryViewController : QLPreviewControllerDataSource {
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
    }
    
    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
        return previewItem as QLPreviewItem
    }
}

extension HistoryViewController {
    func checkURLType(inputURL : URL) -> String {
        
        // Most commom image types..
        let imageExtensions = ["png", "jpg", "gif", "tif", "JPG", "PNG","HEIC"]
        
        // Most cmmon video types..
        let videoExtensions = ["WEBM", "MPG", "MPEG", "MPE", "MP4", "M4P", "M4V", "AVI", "WMV", "MOV"]
        
        let url: URL? = URL(fileURLWithPath: inputURL.path)
        let pathExtention = url?.pathExtension
        
        if imageExtensions.contains(pathExtention!) {
            print("Image URL History: \(String(describing: url))")
            return "Image"
        }else if videoExtensions.contains(pathExtention!) {
            print("Video URL: \(String(describing: url))")
            return "Video"
        }else {
            print("Does Not Exist: \(String(describing: url))")
            return ""
        }
    }
    
    func generateThumbnail(path: URL) -> UIImage? {
        do {
            let asset = AVURLAsset(url: path, options: nil)
            let imgGenerator = AVAssetImageGenerator(asset: asset)
            imgGenerator.appliesPreferredTrackTransform = true
            let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
            let thumbnail = UIImage(cgImage: cgImage)
            return thumbnail
        } catch let error {
            print("*** Error generating thumbnail: \(error.localizedDescription)")
            return nil
        }
    }
}
ios swift uitableview uikit
1个回答
0
投票

这 2 个解决方案对我有用

第一:

我不知道为什么,但是当我尝试评论这个方法时

heightForRowAt
而不是调用
cellForRowAt
方法。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let url = arraySplitArray[indexPath.row]
        if url.absoluteString == "AD" {
            if boolIsNativeAdHide {
                return nativeAdHeight() + 40.0
            }else {
                return 0.0
            }
        }else {
            return 75.0
        }
    }

第二:

每当我尝试将

heightForRowAt
值设置为
UITableView.automaticDimension

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}
© www.soinside.com 2019 - 2024. All rights reserved.