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

Posted

技术标签:

【中文标题】从多个部分 UITableView 中的 UITableViewCell 获取 IndexPath 以响应通知【英文标题】:Get IndexPath from a UITableViewCell in a multiple sections UITableView to respond a Notification 【发布时间】:2018-09-27 11:25:11 【问题描述】:

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

现在,我已经让通知帖子工作并作为信息传递,一个情节对象,如下所示:

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

每个单元格都有一个情节对象。所以我想找到一个单元格的 IndexPath,该单元格的情节对象与从通知传递的情节对象相匹配。

我不知道如何循环遍历我的单元格以找到哪个有该情节并获取它的 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 ......

【问题讨论】:

当您收到通知时,将 id 分配给您的剧集,然后从 userInfo 获取 id,然后循环列表。这样,您将拥有与对象匹配的 id 嗨,Sahil,我的问题就是:如何循环列表? 你能发布你有tableview的ViewController吗?通过删除不相关的代码来发布您的 ViewController。 我刚刚用控制器更新了我的问题。 handleDownloadProgressNotification(notification:Notification) 是我的问题。我如何确定女巫是具有与通知中的情节对象匹配的情节对象的单元格。谢谢你帮助我。 缺少您启动下载的代码 【参考方案1】:

修改你的下载功能并添加以下参数

 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
              ......  
        
    

在您的视图控制器中,将函数替换为以下代码:

@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: $0 == date)
        else return

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

    

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

【讨论】:

很好的答案!谢谢!

以上是关于从多个部分 UITableView 中的 UITableViewCell 获取 IndexPath 以响应通知的主要内容,如果未能解决你的问题,请参考以下文章

标题选择 UITableview 中的多个部分

uitableview 中的多个原型单元,带有部分

UITableView 和 UIButtons 中的多个部分 swift

滚动/调整 UITableView

一个 UITableview 中的多个实体

在 tableviewcell 中使用 UITableview 执行 segue