从多个部分的 UITableView 中的 UITableViewCell 获取 IndexPath 以响应通知

Get IndexPath from a UITableViewCell in a multiple sections UITableView to respond a Notification

我有一个包含多个部分的 tableView,我想在一个单元格中显示(通过通知)Alamofire 正在处理的下载进度。

现在,我已经有通知 post 正在工作并作为信息传递,剧集对象,如下所示:

let info = ["episode": episode, "progress": progress.fractionCompleted] as [String : Any]
NotificationCenter.default.post(name: .downloadProgress, object: nil, userInfo: info)

每个单元格都有一个情节对象。所以我想找到一个单元格的索引路径,该单元格的剧集对象与从通知传递的剧集对象匹配。

我不知道如何循环遍历我的单元格以找到哪个单元格有那一集并获取它的 indexPath 以便我可以正确响应通知。

我试图获取作为 dataSource 的数组的索引,但由于 tableView 有多个部分,这不起作用。

有人可以帮助我吗?谢谢

我的 TableViewController:

//
//  EpisodesViewController.swift
//  Podee
//
//  Created by Vinícius Barcelos on 21/07/18.
//  Copyright © 2018 Vinícius Barcelos. All rights reserved.
//

import UIKit
import RealmSwift
import Kingfisher

class EpisodesTableViewController: UITableViewController {

    //MARK:- Variables
    var episodes: Results<Episode> = RealmService.shared.read(object: Episode.self).sorted(byKeyPath: "pubDate", ascending: true)
    let episodesCellId = "episodesCellId"
    var notificationToken: NotificationToken?

    var episodesDictionary = Dictionary<Date, [Episode]>()
    var dateDays = [Date]()

    //MARK:- Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        setupObservers()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        tableView.reloadData()
    }

    deinit {
        self.notificationToken?.invalidate()
        //NotificationCenter.default.removeObserver(self, name: NSNotification.Name.downloadProgress, object: nil)
    }


    //MARK:- Setup
    fileprivate func setupObservers() {
        NotificationCenter.default.addObserver(self, selector: #selector(handleDownloadProgressNotification(notification:)), name: .downloadProgress, object: nil)
        }
    }

    @objc func handleDownloadProgressNotification(notification:Notification) {
        ////////
    }


    //MARK:- Tableview methods
    override func numberOfSections(in tableView: UITableView) -> Int {
        return episodesDictionary.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let key = dateDays[section]
        guard let datesValues = episodesDictionary[key] else {
            return 0
        }
        return datesValues.count
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd MMMM"
        return dateFormatter.string(from: dateDays[section])
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: episodesCellId, for: indexPath) as! EpisodesTableViewCell

        let key = dateDays[indexPath.section]

        if let podcastValues = episodesDictionary[key] {
            cell.delegate = self
            cell.progressBar.isHidden = true
            cell.episode = podcastValues[indexPath.row]
        }
        return cell
    }

}

下载码:

// Start download
        Alamofire.request(episode.streamURL).downloadProgress { (progress) in
        // Send a notification about the download progress
        let info = ["episode": episode, "progress": progress.fractionCompleted] as [String : Any]
        NotificationCenter.default.post(name: .downloadProgress, object: nil, userInfo: info)
        //print(progress)
        // Check data
    }.responseData { (responseData) in ......

修改你的下载功能,增加以下参数

 func downloadFile(url: String,date: Date, index: Int){
        let utilityQueue = DispatchQueue.global(qos: .utility)
        Alamofire.download(url)
            .downloadProgress(queue: utilityQueue) { progress in
                let info: [String: AnyHashable] = ["date": date,
                             "index" : index,
                             "progress": progress.fractionCompleted
                ]
                NotificationCenter.default.post(name: .downloadProgress, object: nil, userInfo: info)
            }
            .responseData { response in
              ......  
        }
    }

在您的 viewcontroller 中,将函数替换为以下代码:

@objc func handleDownloadProgressNotification(notification:Notification) {
        var dateDays = [Date]()
        guard let info = notification.userInfo,
        let date = info["date"] as? Date,
        let index = info["index"] as? Int,
        let progress = info["progress"] as? Double,
        let section = dateDays.index(where: {[=11=] == date})
        else {return}

        let indexPath = IndexPath(item: index, section: section)

    }

在下载函数中,我们将传递您开始下载的行的日期和索引,您将返回它并通知。您还可以将部分和行索引发送到下载功能。这主要取决于您要如何跟踪该行。你也可以设置委托而不是通知来跟踪下载进度