UICollectionView Cells do not animate movement - ios

When I initiate movement for my collectionView cells, the cells do not move. They move only when I pan my finger over another cell. So if I initiate a movement by pressing one of my cells and then pan, the cells do not track my finger. The only time animation occurs is when my finger pans over another cell. At that point the animation is just the reordering. Bonus: One I end my gesture (lift up my finger) the current cell I was moving around disappears from view. I am using a custom flow layout

My custom flowLayout is stopping the animation. In my custom layout I set the frames of my cells (their attribute frames) to a specific position that is hardcoded in my layout. When the long press gesture is initiated I have to change my attributes somehow.

You don't need to update your attributes. Just make sure you are overriding these methods in your custom layout:
layoutAttributesForElements
layoutAttributesForItem
layoutAttributesForSupplementaryView

Related

Horizontal scroll in collection view

I wish to do something when my collection view cell is scrolled horizontally. But I do not know which function gets called when it is getting scrolled.
I have a collection view cell inside of a table view cell, and the collection view cell scrolls horizontally
If you use storyboard, in Attributed Inspector you will find an option that Scroll Direction, make it Horizontal, default this is set to Vertical
programitically
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
There are several methods that will notify you when a collection view gets scrolled, all of them are contained in UIScrollViewDelegate, and thus in UICollectionViewDelegate protocol, which inherits from the former.
scrollViewDidScroll(_:) is indeed called each time the content offset changes. That means not only the active scrolling issued by the user, but also scrolling by inertia, programmatic scrolling and bouncing. You can use this method to react to the scrolling distance, for example, by querying the contentOffset property of the scroll view.
scrollViewWillBeginDragging(_:) is, in contrast, getting called only at the beginning of scrolling issued by the user (that's why in the documentation you can see that this method may be called only after some delay, since the scroll view's gesture recognizer needs time to decide if it's a tap or a pan gesture). It will not be called again until the user lifts their finger and starts scrolling again.
scrollViewWillBeginDecelerating(_:) is called when the user-issued scrolling discussed above ends, but the scroll view will continue scrolling further to achieve this inertia feeling. Again, it will not get called again until the user lifts their finger one more time.
That's basically it. If this still doesn't narrow down the event that you want to track (for example, you want to become notified when the user starts scrolling at the initial position only), you will need to set some flags or track additional properties.
To track horizontal scrolling for instance, you will need to either compare the scroll view's previous content offset to the current or check the scrolling velocity via scrollView.panGestureRecognizer.velocity(in: collectionView).
First, set your collectionview's delegate to your viewcontroller (or view)
Implement UIScrollViewDelegate methods inside your viewcontroller and you can track your collectionview's scrolling.

ios move touch event between two uiscrollview

I'm building an iOS layout which consists of a UITableView and a UIScrollView. The UIScrollView is inside a table cell of the UITableView and can be scrolled both horizontally and vertically. The diagram below shows this situation. If the user begins scrolling down/up on the UIScrollView the scrolling event should trigger setContentOffset of the table view, and not setContentOffset for the scroll view while the top of the scroll view will be on the dotted line (it's constant height). Then a scrolling touch event should trigger setContentOffset for the scroll view, not for the table view.
In another case: When the user starts scrolling on the table view, it should trigger setContentOffset for the table view, until the scroll view reaches the dotted line. Then the scroll view should handle setContentOffset.
My problem is how to transfer touch events between the table view and the scroll view during one sliding action.
This sounds like one of those cases where you want something quite specific and custom. So trying to do something clever with the gesture recognizers won't be enough.
The main problem is that the ways you can control gesture recognizers such as with gestureRecognizer:shouldReceiveTouch: and gestureRecognizerShouldBegin: only affect the start of the gesture (or for new touches, not ongoing ones), but you want a single ongoing gesture to transition between controlling each view. So for this reason I think you will need to place a large transparent view over your entire screen with a pan gesture recognizer on it and in your handlePan method decide which view you want to adjust and then call setContentOffset directly on that view. You can use the translation of the pan recognizer and the existing content offset to calculate the new one. I know this isn't very elegant, but I can't think of another way to achieve the effect you want.
I'm not sure if this is going to work, but you could try doing something like this:
Option
self.scrollView.panGestureRecognizer = self.tableView.panGestureRecognizer;
Option
[self.scrollView addGestureRecognizer:self.tableView.panGestureRecognizer];
Option
[self.tableView.panGestureRecognizer requireGestureRecognizerToFail:self.scrollView.panGestureRecognizer];

UITableViewCell horizontal custom swip- to-delete effect

I have a UITableView and would like to have a custom way to delete my cells. When someone swipe on it, the cell would move horizontally on the side and disappear.
Exactly like the multitasking menu on iOS 7 (http://movies.apple.com/media/us/ios/ios7/f34c5445-5a9c-4b3a-9556-8efe89147559/shared_multitasking/shared_multitasking_2x.mp4), but instead of swiping vertically, it would be horizontal.
Does any one knows how to do that? Should I just detect a swipe and change the frame of my cell with a 1 sec animation? Or are there nice subclasses of UITableViewCell you would recommend?
I just threw together a very basic example of how to do this and posted it here: https://github.com/NSPostWhenIdle/MMSwipeToDeleteCollection. Don't expect to be able to drag and drop this into your project and have it work, because quite frankly it probably won't.
The basic idea to create something like this starts with a subclass of UICollectionViewCell that adds a gesture to the cell. In my example, I used a swipe gesture because I'm lazy :p and there is more overhead involved in setting up a pan gesture (which you'll want in your end product) because there is conflict between that pan gesture, and the pan gesture in the collection view's scroll view.
From there it's basically smooth sailing. When the gesture recognizer gets called you animate the cell out the top of the screen. If you set this up with a pan gesture, you'll need to configure this to drag the cell, and animate up or down upon completion, but in my swiping example, the cell moves to just out the top (of the 4 inch simulator, I used static values).
Then all that's left to do is some clean up. Once the cell has exited the screen you can safely delete it from your datasource and then from the collection view. (I used notification center do alert the collection view, but you should probably make a protocol) The only issue I had with this was that the cell animated back down while fading out as part of the stock deletion animation. Setting its alpha to 0 after it leaves the screen solves this problem.

Drawing in screen with finger in UITableView

I am following this excellent small tutorial about drawing on screen in the layer of a UIView (subclass).
http://spritebandits.wordpress.com/
It just works.
There is just one thing. I placed this view as subview of a UITableViewCell which, naturally, is displayed as part of a UITableView.
I guess I would have the same issue when I would place it within an UIScrollView. (UITableView inherits from UIScrollView anyway)
Touches are triggered by my painting view as long as their related movement is horizontal. As soon as I move the finger kinda vertical, even partly, then the UITableView takes over and scrolls the table.
Is there any proper way of stopping the Table to taike control of the touches while the touch is actually within my view?
If it is of importance: I am using storyboard. The cell is a prototype cell with its own subclass of UITableViewCell.
I've implemented this using the same class "Canvas" you're saying and also inside a UITableViewCell. But I didn't use the entire cell for drawing, only a UIView inside of the UITableView as a subview.
I reached the whole user experience by activating and deactivating the UITableView scrolling when that UIView (subview of the cell where I allow the drawing) fires touchesBegan or touchesEnded. So when they touch/move inside the UIView, they're drawing. When it's outside, they're scrolling. So they can't scroll on the UIView because they will be drawing.
The problem in your case is that since the whole cell is the view for drawing, the user cannot scroll in this concrete cell because it's the drawing one.
Hope this will help.
I dont have an answer for that. But there is essentially a work around.
You could get the user in to a drawing mode, where the scrolling for a UItableviewcell is disabled and then
once the user is done with drawing, you could enable scrolling again.
Inclusion of a button anywhere on the screen would help you switch modes.

UITableView: Drag'n'drop making space between cells

How would I make the cells, below the one that I drag, go down, making a space for insertion?
Example.
I expect it to behave like following:
This is a pretty good implementation. Basically you have a a gesture recognizer to do a tap and hold and then pan around (the trick begin that you dont move the cell on the pan, you move a UIImageView with a snapshot of the cell)
As the cell moves, you detect which row is beneath, and move the table view's cells accordingly (e.g. with moveRowAtIndexPath:toIndexPath:)

Resources