? ? ? ?我們在開發中有沒有遇到彈出一個氣泡的縮放視圖,起到提示或者引導用戶點擊的作用?我在開發中就遇到了這樣的需求。氣泡是要求從某個角彈出變大,然后又縮回到對應的角。動畫效果:
寫到這我們整理一下思路:
1.首先我們實現簡單的縮放功能,就是設置view的transform屬性嘛。
- (void)showView {? ?
self.transform = CGAffineTransformMakeScale(0.01, 0.01);? ? self.alpha = 0;?? ?? ?
[UIView animateWithDuration:0.3 animations:^{? ? ? ?
self.alpha = 1;? ? ? ?
self.transform = CGAffineTransformMakeScale(1.05, 1.05);? ?
} completion:^(BOOL finished) {? ? ? ?
[UIView animateWithDuration:0.1f animations:^{? ? ? ? ? ? self.transform = CGAffineTransformMakeScale(1, 1);? ? ? ?
} completion:^(BOOL finished){? ? ? ? ? ? //? 恢復原位? ? ? ? ? ? self.transform = CGAffineTransformIdentity;
? ? ? ? }];
? ? }];
}
- (void)hiddenView {? ?
self.transform = CGAffineTransformMakeScale(1 , 1);?? ?? ? [UIView animateWithDuration:0.3 animations:^{? ? ? ? self.alpha = 0;? ? ? ?
self.transform = CGAffineTransformMakeScale(0.01 , 0.01);
? ? } completion:^(BOOL finished) {? ? ? ?
self.transform = CGAffineTransformIdentity;? ? ? ?
self.alpha = 0.0f;? ?
}];
}
2.但是怎么設置動畫的起始位置呢?這是我遇到的問題。下面我們開始探索之旅。首先我想到的就是設置這個view.layer.anchorPoint 錨點屬性.
什么是anchorPoint呢?老規矩看文檔。
You specify the value for this property using the unit coordinate space. The default value of this property is (0.5, 0.5), which represents the center of the layer’s bounds rectangle. All geometric manipulations to the view occur about the specified point. For example, applying a rotation transform to a layer with the default anchor point causes the layer to rotate around its center. Changing the anchor point to a different location would cause the layer to rotate around that new point.
翻譯:您可以使用單位坐標空間為該屬性指定值。這個屬性的默認值是(0.5,0.5),它代表了層的邊界矩形的中心。對視圖的所有幾何操作都發生在指定的點上。例如,使用默認錨點對一個層應用旋轉變換會導致該層圍繞其中心旋轉。將錨點更改為不同的位置會導致層圍繞新點旋轉。
從這個例如中我們就看到了希望,對這個圖層做動畫是圍繞著這個點展開的。直白點說它就是決定我們視圖邊界的哪個點在哪個位置,比如說是中心點、左上角的點、左下角、右上角、右下角的點。
但是決定它位置的是哪個屬性呢?這就需要再次引入另一個屬性view.layer.position。
關于position的文檔說明:
The position in the superlayer that the anchor point of the layer's?bounds rect is aligned to. Defaults to the zero point
翻譯:該層的錨點在超層中的位置。默認值是0。
由此可見這個點是決定著錨點的位置。
通過下圖了解一下position和anchorPoint的關系:
寫到這里我們是不是就有思路了,首先縮放動畫我們有了,我們設置view的錨點為左下角然后再設置position的位置在左下角的點就好了。
但是怎么設置這position的屬性呢?
這里就涉及到UIView和Layer的區別與聯系了:
UIView:用戶交互,界面展示
CALayer:繪制界面,屬于QuartzCore框架(跨平臺的)
總結:UIView負責處理用戶交互,layer負責繪制內容。我們訪問和設置
的UIView的這些負責顯示的屬性實際就是訪問和設置layer對應的屬性,
只不過UIView把他封裝了起來。用一張圖說明一下吧。
從圖中的紅框我們就可以看出了,view的center屬性就是和layer中的position對應的。這樣我們修改view的center屬性就修改了layer的position了。但是有的人問了我可以直接設置這個layer的position屬性不可以嗎?其實是可以的,這里說明一下,要是你布局用的是frame的方式你用設置center和position的方式都是可以的。但是你要是用Masnory的話直接設置View的center屬性更加的方便。
于是我們就可以總結一下:
假設view 的frame為:(0,0,100,80)?
相當于:(CGRectGetMinX(rect),CGRectGetMinY(rect),CGRectGetWidth(rect),CGRectGetHeight(rect))
要想氣泡從某角開始縮放動畫的設置:(示意代碼)
左上角:
view.center = CGPointMake(0, 0);??
view.layer.anchorPoint? =??CGPointMake(0, 0);
左下角:
view.center =?CGPointMake(0, 0 + 80);?
?view.layer.anchorPoint? =??CGPointMake(0, 1);
右下角:
view.center =?CGPointMake(0 + 100, 0 + 80);?
?view.layer.anchorPoint? =??CGPointMake(1, 1);
右上角:
view.center =?CGPointMake(0 + 100, 0);?
?view.layer.anchorPoint? =??CGPointMake(1, 0);
中心點:
view.center =?CGPointMake(0 + 100 / 2, 0 + 80 / 2);?
?view.layer.anchorPoint? =??CGPointMake(0.5, 0.5);
左中:
view.center =?CGPointMake(0 , 0 + 80 / 2);
?view.layer.anchorPoint? =??CGPointMake(0, 0.5);
右中:
view.center =?CGPointMake(0 + 100, 0 + 80 / 2);
?view.layer.anchorPoint? =??CGPointMake(1, 0.5);
上中:
view.center =?CGPointMake(0 + 100 /? 2,? 0);
?view.layer.anchorPoint? =??CGPointMake(0.5, 0);
下中:
view.center =?CGPointMake(0 + 100 /? 2,? 0 + 80);
?view.layer.anchorPoint? =??CGPointMake(0.5, 1);
說了這么多了,不上個demo顯得沒有誠意。您拿好,如果幫到您了支持一下,哪里做的不好請多多指教。https://github.com/WarmLGZ/GZPopScaleView
參考文章:
關于對position和anchorPoint的關系理解:
http://www.lxweimin.com/p/56e61e0de56c
http://www.lxweimin.com/p/94ba4de209ed
關于對transform的理解: