首页 > 解决方案 > 使用文件系统时如何从 TableView 中删除文件夹

问题描述

我创建了一个显示 Documents 目录内容的 TableView 应用程序。我将本地目录的所有元素放入数组“内容”并从该数组加载 TableView。但我只想在 TableView 中查看文件(.mp3)而不是子文件夹。我希望子文件夹甚至不被添加到数组“内容”中。我该怎么做?我尝试在 func cellFoRowAt 中使用 .isDirectory 属性并从数组“content”中删除子文件夹。但是当我尝试删除某些行时应用程序崩溃,这是因为部分中的行数无效。

class TableViewController: UITableViewController {
    
    var currentDirectory: String?
    var content: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        reloadData()
    }
    
    private func reloadData(needsReload: Bool = true) {
        
        if currentDirectory == nil {
            currentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        }
        do {
            content = try FileManager.default.contentsOfDirectory(atPath: currentDirectory! )
        } catch {
            content = []
        }
        if needsReload {
            tableView.reloadData()
        }
    }
    
    private func isDirectory(atPath: String) -> Bool? {
        let url = URL(fileURLWithPath: atPath)
        
        if let object = try? url.resourceValues(forKeys: [.isDirectoryKey]) {
            if object.isDirectory! {
                return true
            } else {
                return false
            }
        } else {
            return nil
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return content.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        cell.textLabel?.text = content[indexPath.row]
        if let directory = isDirectory(atPath: fullPath) {
            if directory {
                content.remove(at: indexPath.row)
                tableView.reloadData()
            } else {
                cell.detailTextLabel?.text = "File"
            }
        }
        ...
        return cell
    }
    
....

标签: iosswiftuitableview

解决方案


这是一个非常糟糕的方法。永远不要删除cellForRowAt.

而不是读取文件名,而是读取 URL 并通过路径扩展名过滤数据。您可以轻松地显示名称lastPathComponent

class TableViewController: UITableViewController {
    
    lazy var currentDirectory : URL = {
        return try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    }()
    
    var content: [URL] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        reloadData()
    }
    
    private func reloadData(needsReload: Bool = true) {
        do {
            let allURLs = try FileManager.default.contentsOfDirectory(at: currentDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles])
            content = allURLs.filter{$0.pathExtension == "mp3"}
        } catch {
            content = []
        }
        if needsReload {
            tableView.reloadData()
        }
    }
    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return content.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        cell.textLabel?.text = content[indexPath.row].lastPathComponent
        
        // ...
        return cell
    }
}

推荐阅读