20141016個人日誌(不用pop,push的動畫實現)

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;

}

    該方法返回羅盤的相對高度,在父類裏調用,在子類裏重寫,調用時覆蓋父類的同名方法。


     數據庫操作時,防止修改失敗,每次都添加事物,利用數據回滾技術。不知道具體怎麼操作。

發佈了33 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章