Mark Carols Mark Carols - 16 days ago 17
iOS Question

Keep a UITableViewCell visible when scrolling? (Swift 3)

Is it possible to make a single

UITableViewCell
stay visible on screen when scrolling (for example, when you scroll down, the cell should always stay visible at the top of the screen). I'm implicitly asking if I can do this with a cell, so don't bother suggesting I should use a table view header or footer, because I was told on this website it's impossible to animate views inside a footer or header view, I REALLY NEED the ability to animate subviews inside the table view (which apparently can only be done in a cell).

So to rephrase: is it in any way possible to keep a cell inside a table view visible at all time when you scroll up or down? If not, is there a 'trick' to animate views inside a footer or header anyway? because like I said, I was told there's no 'legal' way to do this.

Correct me if this is wrong. Thanks!

UPDATE:
To correct myself on some comments I made earlier: it seems it IS possible to animate subviews inside a footer view, but it doesn't work the same way you animate a cell inside a table view, so if anyone knows how to commit animations inside a footer view, feel free to drop some suggestions. Calling
reloadData()
method of the table view works on table view cells, but the footer view completely ignores
UIView.animate(withDuration:)
and just instantly displays the layout changes without animating them.

UPDATE:

if self.didTapOnButton == true {
self.view.layoutIfNeeded()
UIView.animate(withDuration: 0.3, animations: {
bubbleView.backgroundColor = UIColor(red: 255/255, green: 225/255, blue: 68/255, alpha: 1)
containerViewTrailingConstraint.constant = 5
iconImageViewTrailingConstraint.constant = 5
bubbleViewEqualWidthConstraint.constant = 0
self.view.layoutIfNeeded()
}, completion: { (done:Bool) in
UIView.animate(withDuration: 0.2, animations: {
textView.alpha = 1
doneButton.alpha = 1
}, completion: { (done:Bool) in
textView.becomeFirstResponder()
})
})
self.didTapOnButton = false
}


The code that triggers the animations.
self.didTapOnButton
is set to
true
when the button is tapped and immediately after that the table view gets reloaded so this code gets executed once (notice
self.didTapOnButton
gets re-set to
false
after the animation is done). It seems very unlikely the problem is inside this code, though, since it worked perfectly when the cell was still inside the table view, instead of the table view's footer.

Answer

Since you are trying to animate the view in viewForFooterInSection but the footer view is not yet part of the view hierarchy at that point, the animation doesn't occur. The footer view gets added after this function returns and you just see the post-animation view.

Normally I don't like these sort of time-based 'hacks', but this will address your issue by performing the animation after the footer view is in place and I can't think of any other way of doing it reliably.

if self.didTapOnButton == true {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        self.view.layoutIfNeeded()
        UIView.animate(withDuration: 0.3, animations: {
            bubbleView.backgroundColor = UIColor(red: 255/255, green: 225/255, blue: 68/255, alpha: 1)
            containerViewTrailingConstraint.constant = 5
            iconImageViewTrailingConstraint.constant = 5
            bubbleViewEqualWidthConstraint.constant = 0
            self.view.layoutIfNeeded()
        }, completion: { (done:Bool) in
            UIView.animate(withDuration: 0.2, animations: {
                textView.alpha = 1
                doneButton.alpha = 1
            }, completion: { (done:Bool) in
                textView.becomeFirstResponder()
            })
        })
        self.didTapOnButton = false
    }
}