Swipe Animation for remove Cell in UICollectionView - Swift 2.0
The best way to achieve the animation on the cell of UICollectionView
is overriding its layout UICollectionViewLayout
. Its has method which will return the layout attributes of the cell which you want to either appear/insert/delete.
For example: I created a class KDCollectionViewFlowLayout
inheriting UICollectionViewFlowLayout
and override the delete attribute.
class KDCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attribute = super.finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath)
attribute?.transform = CGAffineTransformTranslate(attributes.transform, 0, ITEM_SIZE)
attribute?.alpha = 0.0
return attribute
}
}
Now you need to assign object of this flowLayout to the collection view in either viewDidLoad or you can assign it through storyboard.
let flowLayout = KDCollectionViewFlowLayout()
self.collectionView?.setCollectionViewLayout(flowLayout, animated: true)
Now, you are all set for transformation of cell which you defined in to finalLayoutAttributesForDisappearingItemAtIndexPath
method whenever you perform any delete operation on the collectionView
.
Update
You need delete the items from collection view using batch operation.
collectionView.performBatchUpdates({ () -> Void in
//Array of the data which you need to deleted from collection view
let indexPaths = [NSIndexPath]()
//Delete those entery from the data base.
//TODO: Delete the information from database
//Now Delete those row from collection View
collectionView.deleteItemsAtIndexPaths(indexPaths)
}, completion:nil)
Animation time of UICollectionView on deletion of cell in iOS
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
in the above delegate method, do the following:
NSIndexPath *lIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:lIndexPath];
//Perform flip animation
//_AnimationDuration defined in Constant.h
CGContextRef context = UIGraphicsGetCurrentContext();
context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationDuration:_AnimationDuration];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:cell cache:YES];
[UIView commitAnimations];
//Implementation of GCD to delete a flip item
double delay = _AnimationDuration/2;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//code to be executed on the main queue after delay
[self deleteContent:indexPath];
});
-(void) deleteContent:(NSIndexPath *)_indexPath{
//Remove items from array on delete
[itemArr removeObjectAtIndex:_indexPath.row];
//Reload the items of UICollectionView performBatchUpdates Block
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:@[_indexPath]];
} completion:nil];
}
Swipe to delete on CollectionView
For my own curiosity's sake I tried to make a replicate of what you're trying to do, and got it to work somehow good. It differs from yours in the way I setup the swipe gestures as I didn't use pan, but you said you already had that part, and haven't spend too much time on it. Pan is obviously the more solid solution to make it interactive, but takes a little longer to calculate, but the effect and handling of it, shouldn't differ much from my example.
To resolve the issue not being able to swipe outside the cell I decided to check if the point was in the swiped rect, which is twice the height of the non-swiped rect like this:
let cellFrame = activeCell.frame
let rect = CGRectMake(cellFrame.origin.x, cellFrame.origin.y - cellFrame.height, cellFrame.width, cellFrame.height*2)
if CGRectContainsPoint(rect, point) {
// If swipe point is in the cell delete it
let indexPath = myView.indexPathForCell(activeCell)
cats.removeAtIndex(indexPath!.row)
myView.deleteItemsAtIndexPaths([indexPath!])
}
I created a demonstration with comments: https://github.com/imbue11235/swipeToDeleteCell
I hope it helps you in anyway!
How to perform a zoom-in , zoom-out animation for tableview cells?
I actually figured out a simple way to perform this animation. There might be better ways to do this, but just incase someone needs help in future.
We write 2 functions for zoomIn and zoomOut (can be used anywhere)
func zoomOut(view : UIView,duration : Double,delay : Double)
{
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
view.transform = CGAffineTransform.identity.scaledBy(x: 0.95, y: 0.95)
})
}
func zoomIn(view : UIView,duration : Double,delay : Double)
{
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
view.transform = CGAffineTransform.identity
})
}
Then we write functions for movement (Can be used anywhere)
func movementAnimation(duration:Double,X:CGFloat,Y:CGFloat,item:UIView)
{
UIView.animate(withDuration: duration) {
item.transform = CGAffineTransform(translationX: X, y: Y)
}
}
and finally we combine these 2 to get a similar animation !
zoomOut(view: Table, duration: 0.1, delay: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
movementAnimation(duration: 0.2, X: -500, Y: 0, item: self.Table)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
movementAnimation(duration: 0, X: 500, Y: 0, item: self.Table)
movementAnimation(duration: 0.2, X: 0, Y: 0, item: self.Table)
}
zoomIn(view: self.Table, duration: 0.1, delay: 0.6)
Here first the view is zoomedOut (reduce scale to 0.95) then its moved outside scree with 0.2sec duration.Once its outside screen, its immediately moved to right side of the screen with 0sec duration. Then with a 0.2sec duration we move it back to original position. Now we call zoomIn to get the view back to its original size with a duration of 0.1sec. The 0.5sec is the total amount of time taken for the zoomOut + movementOut + movementIn functions.
And finally reloading the Table
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.Table.reloadData()
}
Hope this helps someone and thx to 'Nikunj Kumbhani' for the pod idea!
CollectionView move to next cell automatically swift
Below is code you can try :
/**
Scroll to Next Cell
*/
func scrollToNextCell(){
//get Collection View Instance
let collectionView:UICollectionView;
//get cell size
let cellSize = CGSizeMake(self.view.frame.width, self.view.frame.height);
//get current content Offset of the Collection view
let contentOffset = collectionView.contentOffset;
//scroll to next cell
collectionView.scrollRectToVisible(CGRectMake(contentOffset.x + cellSize.width, contentOffset.y, cellSize.width, cellSize.height), animated: true);
}
/**
Invokes Timer to start Automatic Animation with repeat enabled
*/
func startTimer() {
let timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("scrollToNextCell"), userInfo: nil, repeats: true);
}
Add swipe to delete UITableViewCell
Add these two functions:
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Swift 3.0:
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Swift 4.2
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
// handle delete (by removing the data from your array and updating the tableview)
}
}
Snap to center of a cell when scrolling UICollectionView horizontally
While originally I was using Objective-C, I since switched so Swift and the original accepted answer did not suffice.
I ended up creating a UICollectionViewLayout
subclass which provides the best (imo) experience as opposed to the other functions which alter content offset or something similar when the user has stopped scrolling.
class SnappingCollectionViewLayout: UICollectionViewFlowLayout {
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) }
var offsetAdjustment = CGFloat.greatestFiniteMagnitude
let horizontalOffset = proposedContentOffset.x + collectionView.contentInset.left
let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)
let layoutAttributesArray = super.layoutAttributesForElements(in: targetRect)
layoutAttributesArray?.forEach({ (layoutAttributes) in
let itemOffset = layoutAttributes.frame.origin.x
if fabsf(Float(itemOffset - horizontalOffset)) < fabsf(Float(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset
}
})
return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
}
}
For the most native feeling deceleration with the current layout subclass, make sure to set the following:
collectionView?.decelerationRate = UIScrollViewDecelerationRateFast
Related Topics
Get Bogus Value When Execute Break Point in a Variable
Continuously Train Coreml Model After Shipping
How to Link to a 3Rd Party Swift Framework
Nsmanagedobject Changes Do Not Trigger Objectwillchange
Read and Write Permission for User Selected Folder in MAC Os App
Slide Sidebar Menu iOS 8 Swift
How to Use Println in Swift to Format Number
How to Debug "Precondition Failure" in Xcode
Swift 4: Nsfilenamespboardtype Not Available. What to Use Instead for Registerfordraggedtypes
How to Bring Nswindow to Front and to the Current Space
How to Convert Anyclass to a Specific Class and Init It Dynamically in Swift
Timestamped Event Matching Error: Failed to Find Matching Element
Macos Command Line Tool with Swift Cocoa Framework: Library Not Loaded
Instance Member Cannot Be Used on Type Class
How to Access a Swift Enum Associated Value Outside of a Switch Statement
Wkwebview Auto Fill Login Form Swift 2
Xcode & Swift - Window Without Title Bar But with Close, Minimize and Resize Buttons