view 的 frame 操作必須是整體的,ios貌似不允許對結構體的單個變量進行賦值,比如形如:
label.frame.size.height = 20;
這樣的操作是不被允許的,但是
label.frame.size = CGSize{20.0,20.0}
卻是被允許的,但是對label的frame的改變是不起作用的。要想改變一個view的frame,必須對其整個frame進行修改,只有對整個的frame屬性作setter操作,系統纔會重新分配位置,否則只改變一部分是不會起作用的。
有時我們在開發時,只用到一個navigationController,但是它控制兩個或多個view,通過添加 button 來實現不同的 view 間切換。比如設置 view 的 hidden 屬性等。這樣實現不同 view 間的切換操作顯得很生硬,沒有 push 和 pop動畫,直接一閃而過。如果想要實現 pop 和 push 動畫,可以按以下操作來實現:
sourceView 和 destView 都加載在 self.view 層,實現從 sourceView 到 destView 的切換。首先是 push 切換:
-(void)switchInViewFrom:(UIView *)sourceView toView:(UIView *)destView withCompletionBlock:(void(^)(BOOL finished))block
{
CGRect sourceViewFrame = sourceView.frame;
sourceViewFrame.origin.x = -sourceViewFrame.size.width;
// sourceView.frame = sourceViewFrame;
CGRect destViewFrame = destView.frame;
destViewFrame.origin.x = destView.frame.size.width;
destView.frame = destViewFrame;
destViewFrame.origin.x = 0;
// [sourceView.superview addSubview:destView];
[UIView animateWithDuration:.25 animations:^{
sourceView.frame = sourceViewFrame;
destView.frame = destViewFrame;
} completion:block];
}
以下是pop切換的動畫效果:
-(void)switchOutViewFrom:(UIView *)sourceView toView:(UIView *)destView withCompletionBlock:(void(^)(BOOL finished))block
{
CGRect sourceViewFrame = sourceView.frame;
sourceViewFrame.origin.x = sourceViewFrame.size.width;
// sourceView.frame = sourceViewFrame;
CGRect destViewFrame = destView.frame;
destViewFrame.origin.x = -destView.frame.size.width;
destView.frame = destViewFrame;
destViewFrame.origin.x = 0;
// [sourceView.superview addSubview:destView];
[UIView animateWithDuration:.25 animations:^{
sourceView.frame = sourceViewFrame;
destView.frame = destViewFrame;
} completion:block];
}
push 操作將舊的View向左移動,新的View從最右開始進入。pop 操作則是將舊的view右移,新的view從左側進入。方法也不難,只是先設置好各自即將進入的位置,然後用動畫實現即可。block裏可以添加完成view切換後的動作。
注意一點,push註釋部分sourceView.frame = sourceViewFrame;我之前是加在上面了,然後動畫實現,中間過渡的時候會有黑色的塊圖顯示,顯得很不友好。這是因爲若加上註釋的代碼,則意味着先將 sourceView 移走,然後再移入 destView,這樣在移入新的 view 之前,顯示的頁面是沒有內容的,故而會有黑色塊圖顯示。
另外,之前想着爲了解決黑色圖塊的顯示問題,還想着對當前的頁面進行截圖來填補,代碼如下:
//截圖處理黑框
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, [UIScreen mainScreen].scale);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *transView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height)];
transView.image = image;
[self.view addSubview:transView];
UIGraphicsEndImageContext();
將上述對 view 的操作換到 viewController 的操作也是一樣的。在不使用 navigation 的 push 和 pop 時,可以按以下操作來處理,可以參考:廖雪峯的官方網頁 http://www.liaoxuefeng.com/article/0013922124509566432675ba57448dda70659ae1f55906d000點擊打開鏈接
- (void)perform
{
UIViewController* source = (UIViewController *)self.sourceViewController;
UIViewController* destination = (UIViewController *)self.destinationViewController;
CGRect sourceFrame = source.view.frame;
sourceFrame.origin.x = -sourceFrame.size.width;
CGRect destFrame = destination.view.frame;
destFrame.origin.x = destination.view.frame.size.width;
destination.view.frame = destFrame;
destFrame.origin.x = 0;
[source.view.superview addSubview:destination.view];
[UIView animateWithDuration:.25
animations:^{
source.view.frame = sourceFrame;
destination.view.frame = destFrame;
}
completion:^(BOOL finished) {
[source presentViewController:destination animated:NO completion:nil];
}];
}
稍加修改就可以實現從左到右的Push切換動畫:
CGRect sourceFrame = source.view.frame;
sourceFrame.origin.x = sourceFrame.size.width;
CGRect destFrame = destination.view.frame;
destFrame.origin.x = -destination.view.frame.size.width;
destination.view.frame = destFrame;
在做步行路線的時候,顯示的 label 擋住了指南針的一部分,需要將指南針的位置下移。只需要重寫一個方法即可:
// 設置羅盤的高度位置
-(float)getInsetFromTop
{
return GENERALIZE_LABEL_HIGHT + _titleView.frame.size.height;
}
該方法返回羅盤的相對高度,在父類裏調用,在子類裏重寫,調用時覆蓋父類的同名方法。數據庫操作時,防止修改失敗,每次都添加事物,利用數據回滾技術。不知道具體怎麼操作。