The Gourmet iOS Developer's Cookbook: Even More Recipes for Better iOS App Development by Erica Sadun
Author:Erica Sadun [Sadun, Erica]
Language: eng
Format: epub
Publisher: UNKNOWN
Published: 2017-04-06T07:00:00+00:00
Implementing Snap Zones
One of my favorite dynamic animator tricks involves creating snap zones—areas of your interface that pull in dragged items once they overlap a particular region. This approach allows you to collect items into well
managed zones and offer a pleasing “snap-into-place” animation. In the general form shown in Listing 6-3, there’s no further test beyond whether a dragged view has strayed into a zone. However, you might want to expand the approach to limit blue items to blue zones or red items to red zones, and so forth.
Listing 6-3 assumes that users will have access to multiple zones and even that a view might move from one zone directly to another. It uses a tagging scheme to keep track of this potential reparenting. A free view has no current parent and can move freely about. When a free view overlaps a snap zone,
however, it suspends
dragging by disabling the view’s gesture recognizer and adds a snap-to-parent
behavior. The view slides into place into its new parent. Once it arrives, as the
dynamic animator pauses, the recognizer is re-enabled.
Allowing a view to escape from its new parent’s bounds is the tricky bit—and the motivating reason for the view tagging. You do not want a view to recapture its child unless the dragging gesture has ended, which is why this method keeps track of the gesture state. With new parents, however, the snap behavior is added (and the gesture is suspended) as soon as a view strays over the line. Balancing the escapes and the captures ensures that the user experience is snappy and responsive and does not thwart the user’s desires to remove a view from a parent.
Listing 6-3 Handling Multiple Snap Zones
Click here to view code image - (void)
draggableViewDidMove: (NSNotification *) note
{
// Check for view
participation
UIView
*draggedView =
note.object;
UIView *nca =
[draggedView
nearestCommonAncestorWithView: _animator.referenceView]; if (!nca) return; UIGestureRecognizerState state = [recognizer state];
// Retrieve state UIGestureRecognizer *recognizer =
(UIGestureRecognizer *)
draggedView.gestureRecognizers.lastObject;
// View frame and current attachment CGRect
draggedFrame =
draggedView.frame; BOOL free =
draggedView.tag == 0; // Make sure all drop zones are views
if (!
[dropZone
isKindOfClass:[UIView class]])
continue; dropFrame);
for (UIView *dropZone in
_dropZones)
{
// Overlap? CGRect
dropFrame =
dropZone.frame;
BOOL overlap =
CGRectIntersectsRect(draggedFrame,
// Free
moving
if (!overlap && free)
{
continue; }
(suspendedRecognizer) {
NSLog(@"Error: attempting to suspend second recognizer"); break; }
suspendedRecognizer.enabled = NO; // stop!
draggedView.tag = CAPTURED
dropZone.tag; // mark as captured
UISnapBehavior *behavior =
[[UISnapBehavior
alloc]
initWithItem:draggedView snapToPoint:RectGetCenter(dropFrame)]; [_animator addBehavior:behavior]; break; }
// Is this the current parent drop zone?
BOOL isParent = (dropZone.tag CAPTURED ==
draggedView.tag); {
case UIGestureRecognizerStateEnded: {
// Recapture
UISnapBehavior *behavior =
[[UISnapBehavior
alloc]
initWithItem:draggedView snapToPoint:RectGetCenter(dropFrame)]; [_animator addBehavior:behavior]; break; }
default: {
// Still captured but no op
break; }
}
break; }
suspendedRecognizer.enabled = NO; // stop!
draggedView.tag = CAPTURED
dropZone.tag;
UISnapBehavior *behavior =
[[UISnapBehavior
alloc]
initWithItem:draggedView snapToPoint:RectGetCenter(dropFrame)]; [_animator addBehavior:behavior]; break; }
}
}
// Newly captured
if (overlap && free)
{
if
// New parent.
//
CAPTURED is an
integer offset for tagging
suspendedRecognizer = recognizer;
// Current parent
if (overlap && isParent)
{
switch (state)
// New parent if (overlap) {
suspendedRecognizer = recognizer;
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Secrets of the JavaScript Ninja by John Resig & Bear Bibeault(6260)
Secrets of the JavaScript Ninja by John Resig Bear Bibeault(5979)
Kotlin in Action by Dmitry Jemerov(4662)
React Native - Building Mobile Apps with JavaScript by Novick Vladimir(2346)
Learning Angular - Second Edition by Christoffer Noring(2177)
Pride and Prejudice by Jane Austen(2108)
Mobile Forensics Cookbook by Igor Mikhaylov(1820)
Computers For Seniors For Dummies by Nancy C. Muir(1778)
Bulletproof Android: Practical Advice for Building Secure Apps (Developer's Library) by Godfrey Nolan(1675)
Building Android UIs with Custom Views by Raimon Ràfols Montané(1626)
Android Development with Kotlin by Marcin Moskala & Igor Wojda(1621)
Building Progressive Web Apps: Bringing the Power of Native to the Browser by Ater Tal(1538)
1936941139 (N) by Bob Rosenthal(1508)
Android App Development by Franceschi Hervé J.;(1502)
Ember.js in Action by Joachim Haagen Skeie(1477)
Hands-On Internet of Things with MQTT by Tim Pulver(1443)
Hands-On Design Patterns with React Native by Mateusz Grzesiukiewicz(1433)
Practical Industrial Internet of Things Security by Sravani Bhattacharjee(1323)
Voice User Interface Projects by Henry Lee(1274)