多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > iOS開發――仿淘寶添加到購物車的動畫效果實現

iOS開發――仿淘寶添加到購物車的動畫效果實現

來源:程序員人生   發布時間:2015-01-09 08:51:20 閱讀次數:7899次

這篇博文實在不知道該起甚么名字才能概況我的意思。。。挫語文水平尷尬

類似于淘寶1樣,我們在寫1些購物、訂餐之類的app的時候,在用戶選擇購買或加入購物車時可以添加1個商品飛到購物車中的動畫效果,以下圖所示:



實現這個效果還是不算難的,但觸及的問題比較多,還是挺有學習價值的。主要面對的問題有以下幾點

1、cell中有button,如何取得該button,即如何知道用戶點擊的是哪個button。

2、坐標系的轉換,這里頻繁使用坐標系轉換,主要緣由是這里需要觸及3個視圖――cell、tableView、view

3、Bezier曲線的利用。

下面我們逐一來解決這些問題。

正好這學期圖形學剛剛結課,雖然沒有甚么關聯,不過也算溫習了- -。


1、獲得cell中的button

這個問題也是個老問題了,方法也非常多,比較常見的是自定義cell,然后將button作為cell的property,這樣我們可以在創建cell的時候為button設tag值,根據indexPath來設便可,通過tag來辨別。這樣在很多情況下也能解決問題。不過這次我們用的其實不是這類方法。

分析:每一個cell的button有自己的處理邏輯,比如,當點擊收藏按鈕時要將選中的FoodModel保存起來,要改變button的標題……,從MVC的原則和職責單1化的原則來看,這些寫在cell以外的地方都是不適合的,而上面的動畫很明顯是在控制器層級的動畫,也就是動畫代碼不能寫在cell中,而是在某某Controller中的。如果只是設tag在控制器中處理是不能實現這個需求的。

既然都要處理,那就將處理邏輯分開便可。說到底這還是代理模式的利用,是類與類之間的通訊問題,用協議、塊、通知都可以。具體來講就是當點擊按鈕時,在cell中處理自己的邏輯,然后把其他任務交給其他類。這里我用的是通知的方法。

固然,再說第2個問題之前先順帶1提,坐標系轉換,很明顯是需要坐標的,我們在控制器中生成動畫的時候,是需要知道點擊的那個cell的某1特定位置(以后會作為動畫的出發點)的坐標,所以在發送通知的時候要自帶上userInfo便于在控制器中取出來。

附上這部份相干代碼:

- (IBAction)tapLikedButton:(UIButton *)sender { //處理自己的邏輯 //if the food has been chosen,then remove it if ([self.likedFoods containsObject:self.foodModel.foodName]) { [self.likedFoods removeObject:self.foodModel.foodName]; [self.foodLikedButton setTitle:@"收藏" forState:UIControlStateNormal]; } else { //like the food and change the title of btn [self.likedFoods addObject:self.foodModel.foodName]; [self.foodLikedButton setTitle:@"取消收藏" forState:UIControlStateNormal]; //將動畫交給其他類去處理 [[NSNotificationCenter defaultCenter] postNotificationName:LIKE_FOOD_NOTIFICATION object:nil userInfo:@{@"position" : [NSValue valueWithCGPoint:[self convertPoint:self.foodNameLabel.center toView:self.superview]]}]; } //save the foods NSString *filePath = [self filePath]; [self.likedFoods writeToFile:filePath atomically:YES]; }

2、坐標系的轉換

其實在上面的代碼中已用到了,還是,做1下分析:這里我們要將1個位置坐標傳出去,但是傳甚么位置呢?如果是Lable的位置簡答的傳出去,那末很明顯會出現1個問題:不管你點擊那個cell的按鈕,動畫都是從同1個出發點動身的,而且絕對不會是任何正確的出發點。由于每一個cell中Label的位置都是1樣的,而我們實際需要的是這個坐標相對TableView的位置,也就是說它在父視圖中的位置,所以這里要將該點坐標轉換。

一樣,上面gif圖片中,可以看到,我們要觸及的視圖有,最右下角有1組圖片和按鈕,表示購物車,在tableView中有我們之前傳過來的坐標,而我們希望讓動畫產生在view層級上,所以這里需要兩次坐標轉換,把右下角的控件集合中的按鈕坐標(購物車是個按鈕)和tableView中的傳過來的出發點坐標都轉換到self.view中,具體做法是

CGPoint endpoint = [self.view convertPoint:btnCenter fromView:carBG];

CGPoint startPoint = [self.view convertPoint:lbCenter fromView:self.tableView];
附:關于坐標轉換,網上也有很多資料,本人之前的博客中也有提及:iOS開發――仿新版iBOOks書本打開與關閉動畫 

有了起止點以后,剩下的就是最關鍵的問題――bezier曲線的使用了。

3、Bezier曲線

關于Bezier曲線,iOS已為我們封裝好了生成操作,我們只需要提供控制點便可。為了更好地理解Bezier曲線,為了以后能更好的利用Bezier曲線來創造好看的效果,我們應當學習其原理與生成機制,這里只做簡單1提,以后再專門學習記錄。。

由于我們想產生1種類拋物線的動畫,所以這里我們需要2階Bezier曲線便可,所以要提供3個控制點,起始點和終止點都已有了,關鍵就是中間的控制點。在計圖實驗中生成Bezier時,我們用的1種思路是以直代曲,用大量短線段來表示1條曲線,每個n階Bezier曲線(n+1個點)在生成時,總能在n個線段中依照1個比例各找出1個點,而這n個點又能生成1個n⑴階Bezier,我們的Bezier曲線上的點就是當只有1條線段以后依照那個比例找出的那個點。

無圖無真相,盜圖可恥,我干脆擺上1個鏈接好了偷笑

Beizer曲線上點的肯定

原理是這樣,我們用起來只要略微了解1點,就知道我們缺少的那個控制點就是在起止點之間,但是縱坐標要比這兩點“高”很多的1個點。所以可以通過下面的公式得出1個控制點

float x = sx + (ex - sx) / 3; float y = sy + (ey - sy) * 0.5 - 400;

由于該控制點的存在,我們的曲線會從起始點向上拋起然后再落到終點處。這里x、y的算法其實不是固定的,可以自由更改,只要符合上面上的條件并且自己覺得好看就好。

利用這3個控制點就可以生成1個2階Bezier曲線,將其作為動畫的path屬性便可。

4、其他方面

UIView的動畫是作用在layer層級的,所以我們可以生成1個CALayer,在這個layer上添加上自己的圖片,然后將動畫利用到這個layer中便可。


附該部份代碼:

- (void)showLikedFoodsAnimation:(NSNotification *)notification { //get the location of label in table view NSValue *value = notification.userInfo[@"position"]; CGPoint lbCenter = value.CGPointValue; //the image which will play the animation soon UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cm_center_discount"]]; imageView.contentMode = UIViewContentModeScaleToFill; imageView.frame = CGRectMake(0, 0, 20, 20); imageView.hidden = YES; imageView.center = lbCenter; //the container of image view CALayer *layer = [[CALayer alloc]init]; layer.contents = imageView.layer.contents; layer.frame = imageView.frame; layer.opacity = 1; [self.view.layer addSublayer:layer]; CGPoint btnCenter = carButton.center; //動畫 終點 都以sel.view為參考系 CGPoint endpoint = [self.view convertPoint:btnCenter fromView:carBG]; UIBezierPath *path = [UIBezierPath bezierPath]; //動畫出發點 CGPoint startPoint = [self.view convertPoint:lbCenter fromView:self.tableView]; [path moveToPoint:startPoint]; //貝塞爾曲線控制點 float sx = startPoint.x; float sy = startPoint.y; float ex = endpoint.x; float ey = endpoint.y; float x = sx + (ex - sx) / 3; float y = sy + (ey - sy) * 0.5 - 400; CGPoint centerPoint=CGPointMake(x, y); [path addQuadCurveToPoint:endpoint controlPoint:centerPoint]; //key frame animation to show the bezier path animation CAKeyframeAnimation *animation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; animation.path = path.CGPath; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; animation.duration = 0.8; animation.delegate = self; animation.autoreverses = NO; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; [layer addAnimation:animation forKey:@"buy"]; }




生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 日本激情啪啪 | 一级做a爱片性色毛片武则天五则 | 在线 | 一区二区三区四区 | 女网址www女影院 | 国产成人啪午夜精品网站男同 | 日韩色视频一区二区三区亚洲 | 黄色毛片大全 | 国产国产成人精品久久 | 秋霞一级 | 伊人久久国产免费观看视频 | 久久精品国产欧美成人 | a级成人毛片久久 | 国产成人咱精品视频免费网站 | 手机看片国产免费久久网 | 欧美综合成人网 | 在线视频国产一区 | 日本高清中文字幕一区二区三区a | 日韩国产在线观看 | 最近更新中文字幕4 | 国产精品久久久久久久hd | 欧美亚洲国产视频 | 亚色国产 | 日本一级做a爱片 | 黄色福利网 | 国产麻豆视频在线观看 | 乱人伦视频69 | 中文字幕一区二区三 | 老司机午夜视频在线观看 | 国产成人精品日本亚洲网站 | 亚洲精品一区专区 | 欧美黄色一级片视频 | 日本理论免费高清在线视频 | 一区二区三区四区无限乱码在线观看 | 精品国产福利片在线观看 | 国产免费久久精品久久久 | 亚洲综合图片 | 在线观看网址 | 国产一区二区精品久久 | 中文字幕巨大乳在线看 | 欧美天天性 | 欧美一区二区三区精品国产 |