Simple collectionView animation - ios

How can i animate the loading of cells into a collectionview.
Ive been playing with the following code but it only animates cells that are off screen when i scroll.
How to animate the all the cells not the screen to start?
let finalFrame: CGRect = cell.frame
cell.frame = CGRect(x: finalFrame.origin.x - 1000, y: -500, width: 0, height: 0)
UIView.animate(withDuration: 0.5, animations: {
cell.frame = finalFrame
})

Use performBatchUpdates(_:completion:)
And inside the performBatchUpdates block:
For items:
Insert: insertItems(at:)
Delete: deleteItems(at:)
Move/Reorder: moveItem(at:to:)
For sections:
Insert: insertSections(_:)
Delete: deleteSections(_:)
Move/Reorder: moveItem(at:to:)
If you want to further customize your animations:
1: Check this thread
2: YouTube tutorial
3: Github Project
4: Alternative UIStackView for Swift 3 Youtube Tutorial

Related

UICollectionView zoom entire grid

I am using a UICollectionView to display a grid of cells with 3 columns. When a cell is selected, I'd like to zoom into the entire collection with the selected cell in the centre. I'd also like to fade out the surrounding cells and keep the selected on at full opacity.
The following code scales the grid but doesn't scroll to the selected cell:
UIView.animate(withDuration: 0.35, animations: {
self.collectionView.transform = CGAffineTransform(scaleX: 3, y: 3)
})
I was hoping I could do it by changing the UICollectionViewFlowLayout and the UICollectionView frame but I'm not sure whether I'm going down the wrong path with this (the following code just moves all the cells over to the left):
UIView.animate(withDuration: 0.35, animations: {() -> Void in
self.collectionView.setCollectionViewLayout(self.zoomedGridLayout, animated: true)
let zoomedRect = CGRect(x: -rect.width, y: 0, width: rect.width*3, height: rect.height)
self.collectionView.frame = zoomedRect
self.collectionView.collectionViewLayout.invalidateLayout()
})
The collection view doesn't need to be scrollable after the animation (I intend to use it only as a transition to another view).

UIView Frame View and CGRect Not Working on First Call

So I am trying to slide a tableview in over top of a lower view, which happens to also to be a uitableview. I have a sandwich icon to slide it in and a close icon to slide it out.
The button switching works great. However, when clicking the close button, the first time, the tableview will not slide out, it will basically slid out and right back to where it is.
However subsequent times, after the close icon switches back to sandwich, and then I click again to bring back close, it will slide it out just fine. Why it not work on the first try.
Below is my code. As you can see my CGRect is supposed to animate and slide the view to the displaywidth X.
#objc func showNewsList(_ sender: UIButton) -> Void {
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
newsIconClose.isHidden = true
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
newsSourceTable.frame = CGRect(x: displayWidth, y: 0, width:
displayWidth, height: displayHeight + 100)
self.addNewsIcon()
})
}
Bingo, figured it out. For whatever reason, CGRect wasn't liked, but this is.
self.newsSourceTable?.frame.origin.x = 0

Send message animation like iMessage send message using UICollectionView customization

I am working on chat application. I am using UIcollectionview for display message. I am trying to create animation on the send button. When the user taps on send UIButton at that I need animation like iMessage.
For creating such animation I use two different ways but not get proper animation.
I created one demo. In that demo, I implemented different approaches.
Demo link:
https://www.dropbox.com/s/z8rxjkpuxzs95kp/AdvanceCollection.zip?dl=0
Below is animation that actually I need:
https://www.dropbox.com/s/yo35lsm7yrc2oqu/Screen%20Recording.mov?dl=0
I apply 2 approaches. Below is approach description.
First approach:
In the first approach, I customized FlowLayout. I know this is proper way but not getting proper curve animation.
override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let attributes = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath),
let added = addedItem,
added == itemIndexPath else {
return nil
}
// set new attributes
attributes.frame = CGRect(x: 0, y: 0, width: 500, height: 500)
//attributes.center = CGPoint(x: self.collectionView!.frame.width - 23.5, y: -24.5)
attributes.center = CGPoint(x: 0.0, y: 100.0)
attributes.alpha = 1.0
attributes.transform = CGAffineTransform(scaleX: 0.15, y: 0.15)
attributes.zIndex = 20
return attributes
}
Second approach: In the second approach, I am implementing animation in willdisplaycell method. According to my point of view, I know this is not the proper approach to customize layout but I tried. In second approach I am getting animation from bottom but x, y, width and height. Also whatever animation is visible is also not same as iMessage send message animation
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !self.collectionData[indexPath.row].isAnimated
{
cell.frame = CGRect(x: 0, y: chatView.frame.origin.y, width: 1000.0, height: chatView.frame.size.height)
UIView.animate(withDuration: 10.0, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.6, options: UIViewAnimationOptions.curveEaseIn, animations: {
cell.frame = CGRect(x:0, y: cell.frame.origin.y, width: cell.frame.size.width, height: cell.frame.size.height)
}, completion: { finished in
self.collectionData[indexPath.row].isAnimated = true
})
}
}
Edit: see tableView demo here animateCell
I think you may try using tableView instead of the collectionView to accomplish that as collectionView layout is awfully silly
I assume you have created a custom xib cell for your collectionView then do this
1- set the top , bottom , leading , trailing constraints properly to the superview of your message label
2- change the top constraint of the message label to be say 400
3- set hook that top constraint as IBOutlet
4- in cellForRowAt set that constraint to say 20
5- then do animation like that
UIView.animateWithDuration(1.0,
{
cell.layoutSubview()
cell.layoutIfNeeded()
}
note: the problem with collectionView is chagning size for item so animation can happen , above solution works perfectly with tableView

How to hide custom view above tableview

I have a tableView with a UIView inside it and I want with the tap of a button to disappear the view.
Because the UIView is inside the tableView (not as a cell, but above the tableView) I can't set a height constraint and make it after 0.
This is the code I use:
UIView.animate(withDuration: 2.0, animations: { () -> Void in
self.infoView.frame = CGRect(x: 0 ,y: 0, width: self.view.frame.width, height: 0)
self.view.layoutIfNeeded()
})
I also tried to set infoView equal to nil (but nothing happened)
Please leave a comment if you don't understand something I said.
Thanks in advance.
Simplest way is hide it, each view has property hidden. https://developer.apple.com/documentation/uikit/uiview/1622585-hidden
change your code
UIView.animate(withDuration: 2.0, animations: { () -> Void in
self.infoView.frame = CGRect(x: 0 ,y: 0, width: 0, height: 0)
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.automatic
self.tableView.reloadData()
})

Running animation on tableViewCell blocks user interaction?

I'm growing a subview of my tableViewCell in an animation.
UIView.animate(withDuration: TimeInterval(timeLeft), delay: 0, options: UIViewAnimationOptions.curveLinear, animations: {
var newFrame = self.viewToScale.frame;
newFrame = CGRect(x: 0, y: newFrame.origin.y, width: newFrame.size.width + CGFloat(widthLeftToGrow) , height: newFrame.size.height)
self.viewToScale.frame = newFrame
})
I'm getting the desired animation, but interacting with my cell has become very unreliable. When I'm trying to swipe to delete I have to spam it until I seemingly swipe at a very specific "right time".
I would assume that I need to run this on a background thread, but updating the UI on the background thread is incorrect isn't it?
How can run this animation on my tableViewCell without sacrificing the users ability to interact with the cell?
change to : options: UIViewAnimationOptions.AllowUserInteraction,
AllowUserInteraction

Resources