Swift: UITableViewCell "jumps" when expanding and a part is out of view - ios

I have an UITableView with custom cells. Cells can be expanded when tapped.
I calculate the height with the delegate heightForRowAtIndexPath
The animation coming with reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) looks really nice but doesn't work if a part of the bigger expanded cell is out of the screen. Then it just kind of pops (it looks like a jump), no nice "sliding"- animation (sorry i don't know the right animation-phrases), like when the cell is completely visible on the screen.
I already tried out reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) that made that nice sliding even if the expanded cell is out of the screen border but the upper part of my cell is just getting brighter for a moment and that doesn't look very fancy..
So anyone having trouble with that "animation" .None, too? ^^"
My did-select-func:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) as? ProviderNewTableViewCell {
if expandedCells.contains(indexPath) {
expandedCells.removeObject(indexPath)
}
else {
expandedCells.append(indexPath)
}
//This prevents the last cell glitching into the decreasing cell above
CATransaction.begin()
CATransaction.setCompletionBlock({ () -> Void in
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
})
CATransaction.commit()
}
}
My cell-for-row-func (the important parts ;) )
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("ProviderNewCell", forIndexPath: indexPath) as! ProviderNewTableViewCell
if expandedCells.contains(indexPath) {
indexPathDetailViewDict[indexPath] = ProviderCellBuilder.sharedInstance.buildDetailView(cell, prov: current)
}
}

Related

Table View insetGrouped Bug

I have expandable table view cells, everything works, except animation. I have one cell with UISwitch, when I tap on it, other cells appear but with some view movements, same thing when I hide these cells when I tap on UISwitch.
I'm using insetGroup Table View and these movements make view square instead of round.
I want to keep animation, I tried reloadSections(IndexSet(integer: 0), with: .fade) seems like a solution, but it also reloads my header, but I don't want that.
My cellForRowAt func:
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RemindersCell", for: indexPath) as! RemindersCell
cell.switchReminder.isOn = remindersAllowed ? true : false
cell.switchReminder.addTarget(self, action: #selector(switchTapped(sender:)), for: .touchUpInside)
return cell
}
My numberOfRowsInSection func:
internal func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return remindersAllowed ? 5 : 1
}
My func for UISwitch:
#objc private func switchTapped(sender: UISwitch) {
if !remindersAllowed {
// Add
remindersAllowed = true
} else {
// Delete
remindersAllowed = false
}
tableView.beginUpdates()
tableView.reloadSections(IndexSet(integer: 0), with: .none)
tableView.endUpdates()
}
Default remindersAllowed is true, when I switch it becomes false and hides cells. I really don't understand what the problem is, any help would be appreciated!
The gif shows this bug when I hide the cells.
you can use activate cell as a tableviewheader
You can try this code to delete system reload section animation and reload section with fade animation:
tableView.reloadData()
tableView.reloadSections(IndexSet(integer: 0), with: .fade)

UITableView left margin checkmark buttons - Swift

I'm trying to add check marks to my UItableview cells. I want to checkmarks to display like circle buttons on the left margin like this image:
I am unable to get the checkmarks in the left margin with my code and instead I keep getting checkmarks on the right that display only when tapped. Here is my current code:
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.accessoryType = .None
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.accessoryType = .Checkmark
}
}
Any idea on how i can get the checkmarks to display on the left like the image?
I've made for you whole sample application for this.
just try this.
And this is what it looks like.

Tableview row, changing last cell changes the first

I'm having a lot of trouble with cell constraint modifications. I have a tableview with a nested cell inside of it and a button.
The bottom more button has a constraint to share the bottom of the cell. There is also a view hiding behind it with a height constraint, you can see it peeking out the bottom.
Basically if I click the the two constraints are changed and the cell is expanded.
TableViewCell:
#IBAction func expandPress(sender: AnyObject) {
if expandButtonBottomConstraint.active {
self.expandButtonBottomConstraint.active = false
self.descriptionTextHeightConstraint.constant =
self.descriptionTextHeightConstraint.constant * 10
self.tableView.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: buttonIndex, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
TableViewController
override func tableView(tableview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let eventCell = tableView.dequeueReusableCellWithIdentifier("EventTableViewCell") as! EventTableViewCell
...
eventCell.buttonIndex = indexPath.row
....
self.tableView.layoutIfNeeded()
}
override func viewDidAppear(animated: Bool) {
self.tableView.reloadData()
}
If you click on the first event it expands, but if you click on on the third one, the third and the first expands. The index row is correctly the right row. How can I only expand a particular row consistently?

Swift - Programmatically set UITableViewCell resets on scroll

So I'm setting a UITableViewCell's layout programmatically when it is selected:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedCellIndexPath = indexPath
var selectedCell = tableView.cellForRowAtIndexPath(indexPath)!
tableView.beginUpdates()
tableView.endUpdates()
var cell:SelectedPatientCell = tableView.dequeueReusableCellWithIdentifier("patient selected", forIndexPath: indexPath) as! SelectedPatientCell
cell.patientName.text = patients[indexPath.row].fullName
cell.dob.text = patients[indexPath.row].dob
...
selectedCell = cell
}
And when I scroll the tableView, the layout of the cell resets to its original layout set in cellForRowAtIndexPath. However, the height stays as it should when I set it in the function above. Does anyone know how to fix this?
Here is an album of what's happening:
http://imgur.com/a/OUIMJ
Image 1:original state
Image 2: selected state (how it should stay on scrolling)
Image 3: what actually happens
you should hold this state in
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath == self.selectedCellIndexPath {
var cell:SelectedPatientCell = tableView.dequeueReusableCellWithIdentifier("patient selected", forIndexPath: indexPath) as! SelectedPatientCell
cell.patientName.text = patients[indexPath.row].fullName
cell.dob.text = patients[indexPath.row].dob
return cell
}
let cell = tableView.dequeueReusableCellWithIdentifier("patient selected") as! OriCell
...
return cell
}
in this way if you scroll tableView,it won't resume to original Cell.
Hopefully it is clear.
So I found my own solution:
Instead of doing
tableView.beginUpdates()
tableView.endUpdates()
I needed to do this at the end of the function:
tableView.reloadData()
and that solves the issue

Changing UITableViewCell height using tableView.beginUpdates()

SO I want to change the height of my UITableViewCell by doing something like this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedIndexPath = indexPath
tableView.beginUpdates()
tableView.endUpdates()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath == selectedIndexPath {
return 140
} else {
return 90
}
}
However, the problem is that when I do this, the cell "expands" slower than the content of expanded portion shows, so whatever is in the expanded portion shows before the cell fully expands and it is kind of ugly. This problem can be fixed if I use tableView.reloadRowsAtIndexPaths(), but I don't want to reload the cell because I have a timer displayed in the expanded portion of the cell.

Resources