0

I have an UITableViewController with UITableView (of course) and my question is how to update data in tableView in runtime?

Because when I call reloadData in viewWillAppear method, it works perfectly, but later in code it does nothing.

Number of rows method is called and returns non-zero number, but cellForRowAtIndexPath is not called so table is not updated...

class CropTableViewController: UITableViewController {

var photos = [Photo]()

var photoAssets = [PHAsset]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.automaticallyAdjustsScrollViewInsets = false
}

override func viewWillAppear(animated: Bool) {
    refreshData()
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("rows called: \(photos.count)")  // prints non-zero 
    return photos.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    print("cell called")

    let cellIdentifier = "Cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CropTableViewCell

    let photo = photos[indexPath.row]


    cell.photoImageView.image = photo.photo

    return cell
}

func refreshData(){
    if (loadPhotos() != nil){
        photos = loadPhotos()!
        tableView.reloadData()
    }

    print("refreshData called \(photos.count)")
}
}

EDIT:

loadPhotos is just loading images from iphone memory:

func loadPhotos() -> [Photo]? {
    return NSKeyedUnarchiver.unarchiveObjectWithFile(Photo.ArchiveURL.path!) as? [Photo]
}

refreshData is called from another class in this cycle:

for asset in photoAssets {
        let manager: PHImageManager = PHImageManager.defaultManager()
        let scale: CGFloat = UIScreen.mainScreen().scale
        let targetSize: CGSize = CGSizeMake(300.0 * scale, 180.0 * scale)

        manager.requestImageForAsset(asset, targetSize: targetSize, contentMode: .AspectFill, options: self.requestOptions, resultHandler: {(image, info) -> Void in
            let photo = Photo(photo: image!)
            self.photos.append(photo!)
            print("photos count \(self.photos.count)")
            self.savePhotos()
            CropTableViewController().refreshData()
        })
    }
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • http://stackoverflow.com/questions/7712325/cellforrowatindexpath-not-called – hasan Mar 30 '16 at 21:02
  • What does `loadPhotos`do? Is it asynchronous? Your code in `refreshData` should obtain the value of `loadPhotos()` and check that for non-nil rather than calling the function twice. Can you show how you are calling `refreshData` "later in code"? – Paulw11 Mar 30 '16 at 21:06
  • I've edited the question. – Tomáš Petrovčín Mar 30 '16 at 21:23

1 Answers1

0

Shot in the dark. Try this:

func refreshData(){
    if let photos = loadPhotos() {
        dispatch_async(dispatch_get_main_queue())
        {
            photos = photos
            tableView.reloadData()
        }  
    }

    print("refreshData called \(photos.count)")
}
Eric Mentele
  • 864
  • 9
  • 16