現在讓我們添加我們的圖標按鈕。
// 添加圖標
UIButton *icon = [UIButton buttonWithType:UIButtonTypeCustom];
[icon setImage:[UIImage imageNamed:@"map-icon"] forState:UIControlStateNormal];
[icon addTarget:self action:@selector(didTapMapIcon:)
forControlEvents:UIControlEventTouchUpInside];
[icon setFrame:CGRectMake(self.window.bounds.size.width - 49, 19, 49, 44)];
[self.window addSubview:icon];
這是一個非常典型的添加圖標按鈕的方式。UIButton
類有一個便利的方式來構建一個按鈕:+buttonWithType:類方法。我將按鈕類型設為UIButtonTypeCustom
,意味著沒有默認的風格會被設置,完全取決於我。這是一種實用的簡單圖標按鈕,沒有邊界和其他怪異的風格需要移除。有點類似於CSS中對按鈕進行重置。
接下來我設置按鈕的圖片為我app包中的“map-icon”圖片。參數UIControlStateNormal
意味著這個圖標會在常規、默認狀態下為顯示按鈕的圖片。你可以用多種圖片多次設置這個值,只要你想要改變圖標,比如UIControlStateHighlighted
狀態。默認情況下,當一個UIButton
被點擊時,iOS會自動暗化圖片。
最後,我讓按鈕可被點擊並且會調用我定義的一個方法。self
參數值意味著我想要這個按鈕調用其被點擊時所在的類,而@selector(didTapMapIcon:)
是我想要調用的Objective-C方法。接下來我通過設置frame將按鈕放置在准確的位置。
讓我們看看現在app的樣子,地圖的alpha值被設為了0,所以它是不可見的。
好,現在我們將動畫的所有主要部件都添加到界面上了,是時候在地圖圖標被點擊時添加一些動畫了。
首先,我們需要實現按鈕被點擊時被調用的方法。這裡是不含任何內容的方法看起來的樣子。
- (void)didTapMapIcon:(id)sender {
// 暫時沒有任何內容!
}
它會在用戶點擊地圖按鈕時被調用,因為我們之前通過 -addTarget:action:forControlEvents:方法進行了設置。
所以,按照邏輯,當你點擊按鈕時,下面兩種事件之一會發生:將地圖動畫到界面上,或者如果地圖已經可見了,則將地圖動畫出界面。我們可以檢查我們的界面元素並查看它們的位置來決定我們應該做什麼,但那太麻煩了,所以讓我們通過一個簡單的作為類@property的 BOOL 變量來跟蹤狀態。在這個文件的頂部我添加了一個名為mapShowing的BOOL變量來管理我們是需要打開還是關閉地圖視圖。這個屬性會放置在我們按鈕方法的下面,而我們添加的其他屬性是我們界面的主視圖。
@interface DTCAppDelegate ()
- (void)didTapMapIcon:(id)sender;
@property (assign) BOOL mapShowing;
@property (strong) UIImageView *appBackground;
@property (strong) UIImageView *mapView;
@end
現在,回到我們的按鈕點擊方法,我們需要在這裡添加一些邏輯,來檢查地圖是顯示還是不顯示,然後將變量設為相反的。
- (void)didTapMapIcon:(id)sender {
if (self.mapShowing) {
self.mapShowing = NO;
// 當地圖已經可見時要運行的代碼
} else {
self.mapShowing = YES;
// 當地圖不可見時要運行的代碼
}
讓我們從else
的情況開始,此時地圖未顯示,我們需要進行不透明度的動畫。我們需要做的是淡出主app背景一點點然後淡入地圖。主app背景的淡出速度會比地圖的淡入速度慢一點點,這樣地圖會更顯眼。
[UIView animateWithDuration:.5 delay:0
options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.appBackground.alpha = 0.3f;
} completion:NULL];
[UIView animateWithDuration:.15 delay:0
options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.mapView.alpha = 1.0f;
} completion:NULL];
你可能注意到了放置在這個基於block的UIView
動畫方法總的options依據裡的巨大的參數。這實際上是兩個選項通過二進制 | 操作組合在一起的:UIViewAnimationOptionCurveEaseInOut
用來定義動畫的淡入淡出,UIViewAnimationOptionBeginFromCurrentState
會從其alpha的當前值開始動畫,這樣即使動畫被打斷了,它也不會跳回開始動畫前的初始值。這對像這樣被用戶動作管理的動畫非常重要,因為你不知道用戶會不會在動畫發生後不停點擊按鈕,而且你肯定不想在動畫完成後都沒做任何事。
當然,調整主app界面和地圖的不透明度並沒有准確地完成我們的動畫,因為我們還需要動畫地圖的比例和位置,這樣它才能夠到達它最終的位置和尺寸。對於主app界面,我們只會稍微動畫其比例。