iphone - Google Now like interface on iOS -
so, absolutely love google now's cards interface on android.. , has come ios.
is there tutorial, or sample project out there can me create cards interface ios applicaion?
from research, have been able replicate "stacked" cards using custom uicollectionviewflowlayout.
- (nsarray *)layoutattributesforelementsinrect:(cgrect)rect { nsarray *allattributesinrect = [super layoutattributesforelementsinrect:rect]; cgpoint centerpoint = cgpointmake(cgrectgetmidx(self.collectionview.bounds), cgrectgetmidy(self.collectionview.bounds)); (uicollectionviewlayoutattributes *cellattributes in allattributesinrect) { if (cgrectcontainspoint(cellattributes.frame, centerpoint)) { cellattributes.transform = cgaffinetransformidentity; cellattributes.zindex = 1.0; } else { cellattributes.transform = cgaffinetransformmakescale(0.75, 0.75); } } return allattributesinrect; }
then set minimum line spacing negative value make them appear "stacked".
upon scrolling though, i'd cards stay @ bottom , 1 car scale , center in screen. scroll card off screen , next 'card' stack scroll stack , center on screen. i'm guessing dynamically adjusting minimum line spacing?
i don't think there's tutorial or class want do. however, if don't mind targeting ios6 , above can use uicollectionview
. using standard vertical flow layout shouldn't hard you're trying achieve. take at:
- http://developer.apple.com/library/ios/ipad/#documentation/uikit/reference/uicollectionview_class/reference/reference.html
- http://www.appcoda.com/ios-programming-uicollectionview-tutorial/
- http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
- wwdc 2012 session 205
i know these examples don't you're trying achieve. once grasp basic concepts of uicollectionview
using these sites, you'll able build cards-layout in no time.
update
i created quick example show potential way handle panning 'away' of cell. make sure add necessary code delete item collection view @ //insert code delete cell here
, fill in gap created removing cell.
clcollectionviewcell.h
#import <quartzcore/quartzcore.h> #import <uikit/uikit.h> @interface clcollectionviewcell : uicollectionviewcell <uigesturerecognizerdelegate> @property (assign, setter = setdeleted:) bool isdeleted; @property (strong) uipangesturerecognizer *pangesturerecognizer; @end
clcollectionviewcell.m
#import "clcollectionviewcell.h" @implementation clcollectionviewcell - (id)initwithcoder:(nscoder *)adecoder { if (self = [super initwithcoder:adecoder]) { // create pan gesture recognizer self set delegate , add cell _pangesturerecognizer = [[uipangesturerecognizer alloc] initwithtarget:self action:@selector(pangesturerecognizerdidchange:)]; [_pangesturerecognizer setdelegate:self]; [self addgesturerecognizer:_pangesturerecognizer]; // don't clip bounds since want content view visible outside bounds of cell [self setclipstobounds:no]; // debugging purposes only: set color of content view [[self contentview] setbackgroundcolor:[uicolor greencolor]]; } return self; } - (void)pangesturerecognizerdidchange:(uipangesturerecognizer *)pangesturerecognizer { if ([self isdeleted]) { // cell should deleted, leave state of cell return; } // percent holds float value between -1 , 1 indicates how user moved finger relative width of cell cgfloat percent = [pangesturerecognizer translationinview:self].x / [self frame].size.width; switch ([pangesturerecognizer state]) { case uigesturerecognizerstatechanged: { // create 'throw animation' , base current state on percent cgaffinetransform movetransform = cgaffinetransformmaketranslation(percent * [self frame].size.width, 0.f); cgaffinetransform rotatetransform = cgaffinetransformmakerotation(percent * m_pi / 20.f); cgaffinetransform transform = cgaffinetransformconcat(movetransform, rotatetransform) ; // apply transformation content view [[self contentview] settransform:transform]; break; } case uigesturerecognizerstatefailed: case uigesturerecognizerstateended: case uigesturerecognizerstatecancelled: { // delete current cell if absolute value of percent above o.7 or absolute value of velocity of gesture above 600 if (fabsf(percent) > 0.7f || fabsf([pangesturerecognizer velocityinview:self].x) > 600.f) { // direction -1 if gesture going left , 1 if it's going right cgfloat direction = percent < 0.f ? -1.f : 1.f; // multiply direction make sure content view removed entirely screen direction *= 1.5f; // create transform based on direction of gesture cgaffinetransform movetransform = cgaffinetransformmaketranslation(direction * [self frame].size.width , 0.f); cgaffinetransform rotatetransform = cgaffinetransformmakerotation(direction * m_pi / 20.f); cgaffinetransform transform = cgaffinetransformconcat(movetransform, rotatetransform); // calculate duration of animation based on velocity of pan gesture recognizer , normalize abnormal high , low values cgfloat duration = fabsf(1000.f / [pangesturerecognizer velocityinview:self].x); duration = duration > 2.f ? duration = 2.f : duration; duration = duration < 0.2f ? duration = 0.2f : duration; // animate 'throwing away' of cell , update collection view once it's completed [uiview animatewithduration:duration animations:^(){ [[self contentview] settransform:transform]; } completion:^(bool finished){ [self setdeleted:yes]; // insert code delete cell here // e.g. [collectionview deleteitemsatindexpaths:@[[collectionview indexpathforcell:self]]]; }]; } else { // cell shouldn't deleted: animate content view original position [uiview animatewithduration:1.f animations:^(){ [[self contentview] settransform:cgaffinetransformidentity]; }]; } break; } default: { break; } } } - (bool)gesturerecognizer:(uigesturerecognizer *)gesturerecognizer shouldrecognizesimultaneouslywithgesturerecognizer:(uigesturerecognizer *)othergesturerecognizer { // return yes make sure pan gesture recognizer doesn't interfere gesture recognizer of collection view return yes; } @end
Comments
Post a Comment