0

I created a UICollectionView with dynamic resizing of cell height. I am resizing the cell like this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let approximatedwidthoftextview = view.frame.width - 70
let size = CGSize(width: approximatedwidthoftextview, height: 1000)
let attributes = [NSAttributedStringKey.font: UIFont(name: "Avenir Next", size: 18)]
let estimatedFrame = NSString(string: allnotes[indexPath.row].note).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
return CGSize(width: view.frame.width, height: estimatedFrame.height + 38)

}

When I delete one cell, the remaining cell’s layout get a bit strange. The content gets cut off.

Strangely enough, navigating to a previous viewcontroller and then coming back to this controller fixes the cell layout and cells go back to normal.

Any idea what’s wrong here?

Normal state State after deleting one cell

import UIKit

private let reuseIdentifier = "Cell"

class AddedNotesCollectionViewController: UICollectionViewController, 
UICollectionViewDelegateFlowLayout {

var allnotes = [notesarray]()


override func viewDidAppear(_ animated: Bool) {

    print(allnotes.count)

}
override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor(red:0.15, green:0.20, blue:0.22, alpha:1.0)
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Register cell classes
    self.collectionView!.register(AddedNotesCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}





override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of items
    return allnotes.count
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    var tag = indexPath.row
    print(tag)

}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! AddedNotesCollectionViewCell

    // Configure the cell

    cell.deleteBtn.layer.setValue(indexPath.row, forKey: "index")
    cell.deleteBtn.addTarget(self, action: #selector(deleteUser(sender:)), for: UIControlEvents.touchUpInside)
    cell.backgroundColor = allnotes[indexPath.row].prioritycolor
    cell.textview.text = allnotes[indexPath.row].note

    // Remove the button from the first cell

    return cell
}
//deleting cell func

@objc func deleteUser(sender:UIButton) {
    let i : Int = (sender.layer.value(forKey: "index")) as! Int
    allnotes.remove(at: i)
    addedNotesArrayGlobal.addednotesarrays.remove(at: i)

    collectionView?.reloadData()



}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    collectionView?.collectionViewLayout.invalidateLayout()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let approximatedwidthoftextview = view.frame.width - 70
    let size = CGSize(width: approximatedwidthoftextview, height: 1000)
    let attributes = [NSAttributedStringKey.font: UIFont(name: "Avenir Next", size: 18)]
    let estimatedFrame = NSString(string: allnotes[indexPath.row].note).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
    return CGSize(width: view.frame.width, height: estimatedFrame.height + 32)
}

}

Osama Naeem
  • 1,830
  • 5
  • 16
  • 34
  • You need to write you code for layout change in viewDidLayoutSubviews(). After delete cell, this method will automatically called, if not, then you need to call. – Sagar Chauhan Nov 11 '17 at 10:33
  • @Jacky can you elaborate a bit more? Which code are you talking about?? – Osama Naeem Nov 11 '17 at 10:35
  • @Jacky confused what ‘layout change code’ will be? InvalidateLayout()? – Osama Naeem Nov 11 '17 at 10:39
  • you need to write code for collection view layout. – Sagar Chauhan Nov 11 '17 at 10:40
  • @Jacky Proper confused. Here's why -> I am changing cell height in 'sizeforitematindexPath' and thats about it. Which collectionViewLayout code you are talking about? – Osama Naeem Nov 11 '17 at 10:44
  • Please try this, https://stackoverflow.com/questions/36884376/swift-how-to-refresh-uicollectionview-layout-after-rotation-of-the-device – Sagar Chauhan Nov 11 '17 at 10:45
  • @Jacky Just tried this. App gets stuck when I try to go the UICollectionViewController ? – Osama Naeem Nov 11 '17 at 10:49
  • Normally this not happening when delete cell, Can you post code to delete cell. ?? – Sagar Chauhan Nov 11 '17 at 10:51
  • @Jacky Just updated the post with full UICollectionViewcontroller code. Look for 'deleteUser' func! – Osama Naeem Nov 11 '17 at 10:54
  • Please continue in chat for your solution. – Sagar Chauhan Nov 11 '17 at 10:58
  • @Jacky dont have enough reputation to start chat:( Can chat on Twitter if you want? – Osama Naeem Nov 11 '17 at 10:58
  • ohk. Have you tried to debug your code in collectionViewLayout method. ?? – Sagar Chauhan Nov 11 '17 at 11:01
  • Nope. How to go about doing that? – Osama Naeem Nov 11 '17 at 11:01
  • Just add break point at first line of code in collectionViewLayout method. first time go directly without debug, then enable or add break points. delete cell and try to find out size of cell and text inside cell. you can find out what actually happening there after delete cell. You need to find value of individual variable used inside methods. – Sagar Chauhan Nov 11 '17 at 11:04
  • @Jacky Just did some debugging. The size of the cell remains fine after deleting the cell. It's the text size that gets all strange after deleting the cell. After deleting the cell: https://imgur.com/a/6M3Dy After going back to previousVC and then returning back to UICollectionViewControllerVC: https://imgur.com/a/z3bSa (Correct state) – Osama Naeem Nov 11 '17 at 11:14
  • @Jacky I can send u my xcode project file if you want to take a closer look? – Osama Naeem Nov 11 '17 at 11:23
  • Did you reload it in main thread? – karthikeyan Nov 11 '17 at 11:25
  • @karthikeyan I think so! – Osama Naeem Nov 11 '17 at 11:26
  • @karthikeyan Just tried that. Still not working. TextView size changes. Cell size remains same(which is good). Any other tips you got? I am doing this to cal it in main thread: self.collectionView?.performSelector(onMainThread: #selector(UICollectionView.reloadData), with: nil, waitUntilDone: true) – Osama Naeem Nov 11 '17 at 11:37
  • @OsamaNaeem. I have one question, Why shouldn't you use tableview instead of collection view. As per your screeen UI, I think it may be easy in tableView. – Sagar Chauhan Nov 11 '17 at 11:40
  • try DispatchQueue.main.async { collectionView?.reloadData() } – karthikeyan Nov 11 '17 at 11:42
  • @Jacky i can try it with tableview as well later. But it would be quite waste of hard work to switch to tableView only to end up having same error with it as well? :( What do u think? Should I switch to tableview? – Osama Naeem Nov 11 '17 at 11:42
  • @karthikeyan not working. Only got one option now: switch it from collectionView to tableView? – Osama Naeem Nov 11 '17 at 11:46
  • If you have time, then better to try some new. And if you know about auto layout, then use it. It will work fine better then calculation of frame and text size. – Sagar Chauhan Nov 11 '17 at 11:46
  • @Jacky exactly. i will try that now:) thanks for the help Jacky!! Will let you know how it goes:) – Osama Naeem Nov 11 '17 at 11:47
  • It's my pleasure. – Sagar Chauhan Nov 11 '17 at 11:48

1 Answers1

0

Even though dynamic resizing works well in collectionView using the above algorithm, it's just not complete. I switched to UITableView and used auto-layouts to do dynamic resizing. It's simple, easy and works quite well.

Osama Naeem
  • 1,830
  • 5
  • 16
  • 34