Reputation: 293
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
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
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