3

So I've got a UITableView loading up many columns of quotes. Upon entering the UITableView that displays this data, the cells seem to initially not be loading properly and the text looks really squished and/or cut off, after about a 1/2 second, it loads properly and everything works fine.

This occurs every time I load up the table view.

For example:

enter image description here

Is this a problem with the .estimatedrowheight...or is it because the view cannot load the data into theUITableView` fast enough? I've tried modifying the row height to no avail however.

Edit

It looks like when I explicity set the height like this -

captionsTableView.rowHeight = 80

it works just fine...as in the cells load at 80points in height each, without the initial loading glitch.

But using captionsTableView.rowHeight = UITableViewAutomaticDimension and captionsTableView.estimatedRowHeight = 80.0 breaks it

Edit 2 - code

class CaptionsController: UIViewController, UITableViewDelegate, UITableViewDataSource  {

  @IBOutlet weak var captionSegment: UISegmentedControl!
  @IBOutlet weak var captionText: UINavigationItem!
  @IBOutlet weak var captionSearchBar: UISearchBar!
  @IBOutlet weak var captionsTitle: UILabel!
  var receiveImage:UIImage!
  //var receiveCategoryText:String!
  //var firstNameCell: UITableViewCell = UITableViewCell()
  //var firstNameText: UITextField = UITextField()
  var model:ModelData!
  let tapRec = UITapGestureRecognizer()
  var currentCell: UITableViewCell!
  var fav: String!
  let basicCellIdentifier = "CustomCells"
  @IBOutlet weak var captionsTableView: UITableView!
  var c: CustomCells!
  var captionJSON: JSON = nil

  override func viewDidLoad() {
    super.viewDidLoad()
    model = (self.tabBarController as CaptionTabBarController).model
    captionJSON = model.quoteSelection()
    captionText.title = model.categoryName
    captionsTableView.delegate = self
    captionsTableView.dataSource = self
    self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "CherrySwash-Regular", size: 25)!,  NSForegroundColorAttributeName: UIColor(red:0.0/255.0, green: 159.0/255.0, blue: 172.0/255.0, alpha: 1.0)]
    configureTableView()
    captionsTableView.reloadData()
    tapRec.numberOfTapsRequired = 2
    tapRec.addTarget(self, action: "tappedView")
    self.view.addGestureRecognizer(tapRec)
    self.view.userInteractionEnabled = true
  }

  func configureTableView() {
    captionsTableView.rowHeight = UITableViewAutomaticDimension
    captionsTableView.estimatedRowHeight = 80.0
  }

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    //deselectAllRows()
    //captionsTableView.reloadData()
  }

  override func viewDidAppear(animated: Bool) {
    captionsTableView.reloadData()
  }

  func deselectAllRows() {
    if let selectedRows = captionsTableView.indexPathsForSelectedRows() as? [NSIndexPath] {
      for indexPath in selectedRows {
        captionsTableView.deselectRowAtIndexPath(indexPath, animated: false)
      }
    }
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return captionJSON.count
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return customCellAtIndexPath(indexPath)
  }

  func customCellAtIndexPath(indexPath:NSIndexPath) -> CustomCells {
    var cell = captionsTableView.dequeueReusableCellWithIdentifier(basicCellIdentifier) as CustomCells
    setTitleForCell(cell, indexPath: indexPath)
    setSubtitleForCell(cell, indexPath: indexPath)
    setImageForCell(cell, indexPath: indexPath)
    return cell
  }

  func setTitleForCell(cell:CustomCells, indexPath:NSIndexPath) {
    let item = captionJSON[indexPath.row]["quote"] 
    cell.mainLabel.text = item.stringValue
  }

  func setSubtitleForCell(cell:CustomCells, indexPath:NSIndexPath) {
    let item = captionJSON[indexPath.row]["author"]
    cell.creditLabel.text = item.stringValue
  }

  func setImageForCell(cell:CustomCells, indexPath:NSIndexPath) {
    //let item = Array(Array(model.quoteItems.values)[indexPath.row])[1] as? String
    //if (item == "fav") {
      //cell.favImgView.image = UIImage(named: "icon-heart-fav")!
    //} else {
      cell.favImgView.image = UIImage(named: "icon-heart")!
    //}
  }

  func tappedView(){
    //need to add filled icon, as well as logic to not change image upon select of favorited cell
    var image : UIImage = UIImage(named: "icon-heart-fav")!
    c.favImgView.image = image
  }

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    c = captionsTableView.cellForRowAtIndexPath(indexPath) as CustomCells
    var captiontabBar:CaptionTabBarController = CaptionTabBarController()
    model.quote = c.mainLabel.text!
    model.author = c.creditLabel.text!

    println(" quote!!! " + model.quote)

    self.tabBarController?.selectedIndex = 0

    //let secondViewController:SelectionsController = SelectionsController()

    //self.presentViewController(secondViewController, animated: true, completion: nil)

    //let returnController = self.storyboard!.instantiateViewControllerWithIdentifier("selections") as? UIViewController
    //self.presentViewController(returnController!, animated: true, completion: nil)


    /*for tempCell: UITableViewCell in tableView.visibleCells() as [UITableViewCell] {
      var image : UIImage = UIImage(named: "icon-heart")!
      tempCell.imageView?.image = image
    }

    var image : UIImage = UIImage(named: "icon-heart-overview")!
    c.favImgView?.image = image*/
  }

}

class CustomCells: UITableViewCell {
  @IBOutlet var mainLabel: UILabel!
  @IBOutlet var creditLabel: UILabel!
  @IBOutlet var favImgView: UIImageView!
}
jshbrmn
  • 1,737
  • 3
  • 22
  • 52
  • What happens if you modify the estimatedRowHeight to a constant value? Though I don't think that's your problem. Looking at the animation, something is happening in `viewDidAppear` or the information is loaded asynchronously. – Lord Zsolt Mar 25 '15 at 18:41
  • 2
    If nothing else you should get +1 just for adding animation ... post your Table code. – Sam B Mar 25 '15 at 18:44
  • 1
    Without seeing more code I can just guess at what you've implemented, but maybe this related question will help: http://stackoverflow.com/questions/19374699/is-there-a-way-to-update-the-height-of-a-single-uitableviewcell-without-recalcu – Alex Mar 25 '15 at 18:45
  • @SamB oh yeha, haha of course...duh...posting – jshbrmn Mar 25 '15 at 18:47
  • I tried to reproduce your error, but I'm not sure my data setup behaves the same way as yours. For me, it worked correctly if I removed the viewDidAppear method (I could also eliminate the other call to reloadData in viewDidLoad, and it worked correctly). – rdelmar Mar 26 '15 at 01:41
  • @rdelmar the thing is, when I set the height of the cells explicitly (`captionsTableView.rowHeight = 80`), it works just fine. Only when I auto-resize each cell does it give me issue. So to me that is an indicator that it isn't the data being retrieved that's the issue, or the issue would always occur. – jshbrmn Mar 26 '15 at 17:30
  • Well, in my tests (just using an array as the data source) I didn't see that problem when I removed the reloadData, even with the estimated height, so I don't know what that says about the cause. But even with the reloadData in there, the problem I saw was the opposite of what you're seeing -- it loaded correctly first, and then rapidly changed to a single line truncated text (but the cells weren't squished like yours). It's a mystery. – rdelmar Mar 27 '15 at 01:01
  • Yeah, I've tried various configurations with varying degrees of success, but the primary issue remains...the view, at some point displays this (or similar [as you've experienced]) issue. I suspect it has something to do with the process going on between `viewWillAppear` -> `viewDidLoad` -> `viewDidAppear` – jshbrmn Mar 27 '15 at 15:06

1 Answers1

1

Add your code in (void)viewWillAppear:

Looks like you are doing it in viewDidload.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (![self.p_tableView respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)])
    {
        self.p_tableView.rowHeight = UITableViewAutomaticDimension;
        self.p_tableView.estimatedRowHeight = 100.0f;
    }
}
Sam B
  • 27,273
  • 15
  • 84
  • 121
  • I added said things like so - `override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) captionsTableView.rowHeight = UITableViewAutomaticDimension captionsTableView.estimatedRowHeight = 80.0 }` to no avail – jshbrmn Mar 25 '15 at 19:02
  • this is in swift by the way :p I'm not sure how to translate that if statement from obj-c (new to both) – jshbrmn Mar 25 '15 at 19:02
  • cut and paste everything you got under viewDidLoad and paste it in viewWillAppear. Make sure to add configureTableView() as well. – Sam B Mar 25 '15 at 20:09
  • same behaviour unfortunately :( – jshbrmn Mar 25 '15 at 20:52