Zash__
Zash__

Reputation: 293

Expand Cell at selectedIndex

Updated Code Below

I am working on comment cells who are limited to 100 characters and if they contain more a "show more button" will show up.

If pressed, the exact cell should reload itself with the number of lines changed to 0 and fully display the cell, no matter how big.

What I have achieved is that cells reload, but not the selected one and kinda arbitrary.

Below is my code for the enlarging process

NOTE: Updatet Code for My Function

Problem: I have to press the button twice to get the result, to minimize and to maximize the cell

   @IBAction func readMore(_ sender: UIButton) {


    self.state = !self.state

    print("state" , state)
    self.tapMore.setTitle(self.state ? self.decreaseState: self.expandState, for: .normal)
    self.commentLabel.numberOfLines = (self.state ? self.expandedLines: self.numberOfLines)
    print(self.commentLabel.numberOfLines)
    let myIndexPath = IndexPath(row: sender.tag, section: 0)

    UIView.animate(withDuration: 0.3, animations: {
        self.parentViewControllerCommentCell?.tableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
    })
}

The index comes from

extension CommentTableViewCell {

var indexPath: IndexPath? {
    return (superview as? UITableView)?.indexPath(for: self)
   }
}

Note

The print statement prints out the chosen cell ( e.g. [0, 1] or [0,0] but it doesn't change then.

Whereas I hardcode my code and change let myIndexPath = IndexPath(row: indexPath!.row, section: 0)

to let myIndexPath = IndexPath(row: 0, section: 0)

The feature works, but arbitrarily reloads some cells and arbitrarily enlarges and decreases the cell.

In the variable version with row: indexPath!.row the lines state doesn't change as well, whereas with hardcoded the lines change between 3 and 0.

Thanks for your help :)

Addition

my commentCell

class CommentTableViewCell: UITableViewCell {

@IBOutlet weak var likeCountButton: UIButton!
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var commentLabel: KILabel!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var likeImageView: UIImageView!


@IBOutlet weak var tapMore: UIButton!

@IBOutlet weak var tapMoreButton: UIButton!


var delegate: CommentTableViewCellDelegate?
var postId : String!

Upvotes: 3

Views: 387

Answers (2)

Saqib Omer
Saqib Omer

Reputation: 5477

You take class variable and track tap counts. Depending on these variables you can increase or decrease size of cell and reload it.

In YOURViewController declare variables as:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

       @IBOutlet weak var CommentsTableView: UITableView!
       var defaultSizeOfCell = 60.0
       var newSize = 80.0
       var selectedIndex = -1

       var isExpanded = false
       var expandCounter = 0
       override func viewDidLoad() { ...

Connect button in cell to this action:

@IBAction func moreButtonAction(_ sender: UIButton) {

    if !isExpanded {
        if expandCounter == 0 {
            expandCounter = expandCounter + 1
        } else if expandCounter == 1 {
            expandCounter = 0
            isExpanded = true
            selectedIndex = sender.tag
            let myIndexPath = IndexPath(row: sender.tag, section: 0)

            UIView.animate(withDuration: 0.3, animations: {
                self.CommentsTableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
            })
            print("Increase")
        }
    } else if isExpanded {
        if expandCounter == 0 {
            expandCounter = expandCounter + 1
        } else if expandCounter == 1 {
            expandCounter = 0
            isExpanded = false
            selectedIndex = -1
            let myIndexPath = IndexPath(row: sender.tag, section: 0)

            UIView.animate(withDuration: 0.3, animations: {
                self.CommentsTableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
            })
            print("Decrease")
        }
    }


}

In tableview datasource function add tag to button:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath) as! TestTableViewCell
    cell.moreButton.tag = indexPath.row
    return cell
}

And finally add this delegate method for height of cells:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if selectedIndex == indexPath.row {
        return CGFloat(newSize)
    } else {

        return CGFloat(defaultSizeOfCell)

    }

}

Not to mention, button should be in cell and connected to YOURCustomTableViewCell class as:

class TestTableViewCell: UITableViewCell {

      @IBOutlet weak var moreButton: UIButton!

I have tested it against your requirements.

Upvotes: 0

Fangming
Fangming

Reputation: 25261

Here is a better approach to get you the correct index path. First, in your cellForRow method, add the current index row as tag to your show more button, and then add click action to your button handler function.

Add an outlet of UIButton in you custom UITableViewCell class as

class CustomCell: UITableViewCell {
     @IBOutlet var moreButton: UIButton! // Connect your button from storyboard
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
    cell.moreButton.tag = indexPath.row
    /* Just add action normally from storyboard. No need to add target. cell.moreButton.addTarget(self, action:#selector(buttonUp(sender:)), for: .touchUpInside) */

    return cell
}

Then in your handler function, you can get the correct index path by reading this tag

func tapForMore(sender: UIButton) {
    let myIndexPath = IndexPath(row: sender.tag, section: 0)
    print("myindex", myIndexPath)
    //... other code here
}

Upvotes: 1

Related Questions