Swift如何在UITableView中为多个部分

时间:2016-09-01 23:58:45

标签: ios swift uitableview caching

我是Swift的新手。我想在我的tableview中显示图像。我正在关注这个tutorial

在我的UITableView中,如tutorial所示。我将图像存储在缓存中。如果tableview只有一个部分,这可以正常工作。如果我的tableview中有多个部分,我应该如何设置forKey值? 如何根据部分和行设置此值self.cache.setObject(image!, forKey:indexPath.row)?谢谢!!

这是我UITableView

的代码
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
    if(tableView == tableview){
        return categoryArray.count
    }else{
        return 1
    }
}

func tableView(tableView : UITableView,  titleForHeaderInSection section: Int)->String
{
    if(tableView == tableview){
        return categoryArray.objectAtIndex(section) as! String
    }else{
        return ""
    }
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if(tableView == tableview){
        print("Count = \(myList[section].count)")
        return myList[section].count
    }
    else{
        return 5
    }

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    if(tableView == tableview) {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomEventCell

cell.cellBackgroundImg.image = UIImage(named: "placeholder")


        if (self.cache.objectForKey(indexPath.row) != nil){
            print("Cached image used, no need to download it")
            cell.cellBackgroundImg?.image = self.cache.objectForKey(indexPath.row) as? UIImage
        }else{

            let img_url = myList[indexPath.section].objectAtIndex(indexPath.row).objectForKey("image") as? String

            if img_url != nil{
                print("Load the image from URL")
                let url = NSURL(string: img_url!)!
                let request = NSMutableURLRequest(URL:url)
                let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
                let task = defaultSession.dataTaskWithRequest(request, completionHandler: {(data:NSData?, response:NSURLResponse?, error: NSError?) in

        dispatch_async(dispatch_get_main_queue(), { () -> Void in

                        let image = UIImage(data: data!)
                        cell.cellBackgroundImg?.image = image
                        self.cache.setObject(image!, forKey:indexPath.row)
                    })
                })
                task.resume()

            }
        }
        return cell
      }   
    }

3 个答案:

答案 0 :(得分:1)

本教程的作者似乎在选择使用indexPath.row作为缓存的关键时犯了一个错误。行号与图像的链接非常脆弱;识别图像的是它的URL。通过使用该行,会出现以下问题:

  • 行号更改(错误的缓存命中)
  • 有多个部分(只是你发现的一般icky)
  • 在多行中使用相同的图像(不必要的缓存未命中)。

您可以轻松修改cellForRowAtIndexPath以将URL用作缓存键:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell = UITableViewCell()
    if(tableView == tableview) {
        let customCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomEventCell
        customCell.cellBackgroundImg.image = UIImage(named: "placeholder")

        if let img_url = myList[indexPath.section].objectAtIndex(indexPath.row).objectForKey("image") as? String {

            if let image = self.cache.objectForKey(img_url) as? UIImage {
                print("Cached image used, no need to download it")
                cell.cellBackgroundImg?.image = image
            } else {
                print("Load the image from URL")
                if let url = NSURL(string: img_url)
                    let request = NSMutableURLRequest(URL:url)
                    let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
                    let task = defaultSession.dataTaskWithRequest(request, completionHandler: {(data:NSData?, response:NSURLResponse?, error: NSError?) in

                        guard let downloadData= data && error == nil else {
                            print("error downloading image:\(error)"
                            return
                         }
                         dispatch_async(dispatch_get_main_queue(), { () -> Void in
                             if let image = UIImage(data: data) {
                                 customCell.cellBackgroundImg?.image = image
                                 self.cache.setObject(image, forKey:img_url)
                             }  
                          })
                    })
                    task.resume()
                }
           }
        }
        cell = customCell
    }
    return cell  
}

你的代码也不是很防守。如果数据不正确,有很多强制解包会给你一个例外

答案 1 :(得分:0)

问题是您使用UITableView引用缓存所有图片,但如果您的self.cache.setObject(image!, forKey:"\(indexPath.section)-\(indexPath.row"))) self.cache.objectForKey(indexPath.row) 有多个部分,则会有重复的行值。例如:

第0节&gt;第0行,第1行,第2行 <第1节>第0行,第1行 <第2节>第0行

所有部分都有&#34;第0行和第34行。

要修复它,你必须这样做:

1)创建格式化的键,例如&#34; SECTION-ROW&#34;,例如:

my_app_name

2)只需使用类似:https://github.com/Haneke/HanekeSwift

的库

答案 2 :(得分:0)

您也可以使用tag。这是使用标记值的代码。您也可能需要考虑代码中的错误处理。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell = UITableViewCell()
    if(tableView == tableview) {
        let customCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomEventCell

      customCell.eventTitle.text = title
        customCell.cellBackgroundImg.image = UIImage(named: "placeholder")
        // calculate tagValue and set it to cache objectForKey
       // here I have taken big numbers so same number will not repeat 
        let tagValue = (indexPath.section * 100) + indexPath.row + 200

        if (self.cache.objectForKey(tagValue) != nil){
            print("Cached image used, no need to download it")
            customCell.cellBackgroundImg?.image = self.cache.objectForKey(tagValue) as? UIImage
        }else{

            let img_url = myList[indexPath.section].objectAtIndex(indexPath.row).objectForKey("image") as? String

            if img_url != nil{
                print("Load the image from URL")
                let url = NSURL(string: img_url!)!
                let request = NSMutableURLRequest(URL:url)
                let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
                let task = defaultSession.dataTaskWithRequest(request, completionHandler: {(data:NSData?, response:NSURLResponse?, error: NSError?) in

                    if error != nil {
                        print(error)
                        return
                    }else if(data != nil){
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            let image = UIImage(data: data!)
                            customCell.cellBackgroundImg?.image = image
                            self.cache.setObject(image!, forKey:tagValue)
                        })
                    }else {
                        print("Error : Image data is nil")
                    }
                })
                task.resume()
            }
            else {
                print("Error : Image URL is nil")
            }

        }
       cell = customCell
    }
    return cell
}