Swipe Animation for Remove Cell in Uicollectionview - Swift 2.0

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



Leave a reply



Submit