UITableView在视图控制器第二次加载时无法重新加载数据

3

我有一个UITableView,其中自定义单元格显示了可下载的文件列表。该单元格显示文件名和下载状态。除了一个情况外,一切正常:

  1. 用户下载文件并在文件下载过程中导航回主屏幕...
  2. 他回到之前的屏幕。文件下载仍在进行中。
  3. 文件下载完成。此时,我使用tableview.reloadData()来将下载状态刷新为“下载完成”,但是reloadData()在这种情况下不起作用。单元格标签仍然显示“下载进行中”。

滚动tableview以使单元格离开屏幕再返回可以正确刷新单元格。有没有办法以编程方式实现?

否则,在用户未更改屏幕的正常情况下,reloadData()工作正常。

有任何想法如何解决这个问题吗?

谢谢

我在我的UIViewController中使用了带进度的alamofire下载函数,如下所示:

func DownloadFile(fileurl: String, indexPath: NSIndexPath, itemPath: String, itemName: String, itemPos: String, ItemSelected:Bool) {

      let cell = myTableView.cellForRowAtIndexPath(indexPath) as! myCustomCell

      let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)


        Alamofire.download(.GET, fileurl, destination: destination)


       .progress {bytesRead, totalBytesRead, totalBytesExpectedToRead in


            // This closure is NOT called on the main queue for performance
            // reasons. To update your ui, dispatch to the main queue.
            dispatch_async(dispatch_get_main_queue()) {
                print("Total bytes read on main queue: \(totalBytesRead) / \(totalBytesExpectedToRead)")


                let progress = Int((Double(totalBytesRead)/Double(totalBytesExpectedToRead)) * 100)


                cell.lblMoreRuqyaFileInfo.text = "Downloading file...(\(progress)%)"


            }
        }
         .response { _, _, _, error in

           if let error = error {
                print("\(error)")
                cell.lblMoreRuqyaFileInfo.text = "Failed to download file. Please try again."
            } else {


            cell.lblMoreRuqyaFileInfo.text = "File Downloaded sucessfully"

          //reloadData() not working from here
            self.myTableView.reloadData()

            }

    }

}

上述函数在下面的tableview的editActionsForRowAtIndexPath中被调用。

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

    if myTableView.cellForRowAtIndexPath(indexPath) == nil {
        let action = UITableViewRowAction()
          return [action]

    }

    let cell = myTableView.cellForRowAtIndexPath(indexPath) as! myCustomCell

    let fileurl = cell.textLabel!.text
    let ruqyainfo = cell.lblMoreRuqyaFileInfo.text

    let sItemPath = cell.lblCompiledRuqya.text! + "->" + cell.textLabel!.text! + "->\(indexPath.section)->\(indexPath.row)"
    let sItemName = cell.lblCompiledRuqya.text!
    let sItemPos = "->\(indexPath.section)->\(indexPath.row)"
    var bItemSelected:Bool = false
    if myTableView.cellForRowAtIndexPath(indexPath)?.accessoryType == UITableViewCellAccessoryType.Checkmark {
        bItemSelected = true
    } else {

        bItemSelected = false
    }

     //check if file already downloaded,return empty action, else show Download button
    if ruqyainfo?.containsString("Download") == false {
        let action = UITableViewRowAction()
         return [action]

    }


    let line = AppDelegate.dictCompiledRuqya.mutableArrayValueForKey(AppDelegate.dictCompiledRuqya.allKeys[indexPath.section] as! String)

    let name = line[indexPath.row].componentsSeparatedByString("#")

    let DownloadAction = UITableViewRowAction(style: .Normal, title: "Download\n(\(name[3]))") { (action: UITableViewRowAction!, indexPath) -> Void in

            self.myTableView.editing = false

            AppDelegate.arrDownloadInProgressItem.append(name[0])

            self.DownloadFile(fileurl!, indexPath: indexPath, itemPath: sItemPath, itemName: sItemName,itemPos: sItemPos, ItemSelected: bItemSelected)

        }

    DownloadAction.backgroundColor = UIColor.purpleColor()
    return [DownloadAction]
}

请展示你的代码的这一部分。 - Ro22e0
在下载完成的方法中,你必须调用reload方法。 - Aly
尝试重新绘制视图控制器(同时在viewdidappear中重新加载数据).. http://stackoverflow.com/questions/16225397/how-to-refresh-uiviewcontroller-programmatically - mkumar
5个回答

0
//Objective C
    -(void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
       [self.yourTableView reloadData];
    }

//Swift
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.yourTableView.reloadData()
}

是的,这样做不起作用,因为下载仍在进行中,而屏幕已经第二次加载。在viewWillAppear中使用reloadData()在这种情况下也无济于事。 - john doe
你能否添加一些关于你的代码的细节,以及它如何解决问题?仅有代码的回答并不是很有用,特别是对于未来遇到这篇文章的读者。谢谢。 - Cristik
很明显,他每次视图再次可见时都会刷新,因此它应该始终保持最新状态。 - Gil Sand

0

你可以使用委托,这样下载控制器就可以告诉第一个控制器下载已完成,并且它应该重新绘制tableView - 或者至少是刚刚完成的indexPath。

像这样设置下载控制器

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    let destinationController : DownloadController = segue.destinationViewController as! DownloadController
    destinationController.delegate = self

    destinationController.indexRowToRefresh = currentlySelectedIndexRow        
}

然后在下载完成的闭包中,添加类似以下的内容

   delegate.refreshTableRow(indexRowToRefresh)

在你的第一个控制器中,实现委托方法来刷新这一行(或整个表格)

func refreshTableRow(indexRowToRefresh : Int)
{
    var indexPath = NSIndexPath(forRow: indexRowToRefresh, inSection: 0)
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
}

0

可能是线程相关的问题(也就是说,你从下载线程返回,而不是在UI线程上,因此数据已经刷新但没有显示)。

尝试在self上使用这个方法,并传递一个刷新你的tableview的选择器。

performSelectorOnMainThread:

我已经尝试过了,但它也不起作用! self.myTableView.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true) - john doe

0

嘿@John,请确保您的TableView数据源始终反映文件上传状态。

我认为,当您完成文件上传时,您会在tableview数据源中更改状态。

1.第一种情况是,当您切换到第二个视图控制器并返回到上一个视图时,它可能会重新初始化您的数据源。数据源可能没有永久反映。
2.在正常情况下,由于您在同一个视图控制器上(不切换到其他视图),因此Tableview数据源可能不会重新初始化,从而保持更新的文件上传状态。

我建议将用户文件下载状态保存在某些持久存储或Web服务器上。这不会导致数据不一致。


0

你使用了:

let cell = myTableView.cellForRowAtIndexPath(indexPath) as! myCustomCell

并设置 lblMoreRuqyaFileInfo 的文本:

cell.lblMoreRuqyaFileInfo.text = "File Downloaded sucessfully"

所以,你不必调用 self.myTableView.reloadData()
尝试:

dispatch_async(dispatch_get_main_queue()) {
        cell.lblMoreRuqyaFileInfo.text = "File Downloaded sucessfully"
    }

顺便问一下,你在哪里调用了DownloadFile函数?请展示一下!


我已经尝试过了...但它仍然无法工作。只有在文件下载时,用户导航到主屏幕并返回到tableview屏幕时才会出现此问题。状态标签随后显示“正在下载...”。然后,在仍然在同一屏幕上的情况下,下载完成。这时调用reloadData()来更改标签。我是从editActionsForRowAtIndexPath tableview函数中调用Downloadfile函数的。 - john doe
我已经将其粘贴在上面。 - john doe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接