iOS程序員面試分類模擬10_第1頁
iOS程序員面試分類模擬10_第2頁
iOS程序員面試分類模擬10_第3頁
iOS程序員面試分類模擬10_第4頁
iOS程序員面試分類模擬10_第5頁
已閱讀5頁,還剩9頁未讀 繼續免費閱讀

付費下載

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

iOS程序員面試分類模擬10簡答題1.

UIView動畫原理是什么?以UIView類的animateWithDuration方法為例?正確答案:iOS4.0以后提供了幾個基于block塊的動畫方(江南博哥)法(UIView類的+animateWithDuration類方法),替代之前的+beginAnimations:context:和+commitAnimations方法,用于快速實現一些簡單常用的UI動畫效果。這種方法創建的動畫為隱式動畫,開發者只需要指定UI元素的一些屬性的目標值,即可得到屬性從當前值平滑過渡到目標值的動畫效果,同時可以指定動畫的持續時間。

可以設置UI隱式動畫的常用屬性主要有frame、bounds、center、transform、alpha、backgroundColor、contentStretch等。

例如,實現一個讓視圖平滑移動到指定位置的動畫代碼如下:

[UIViewanimateWithDuration:0.3animations:^{

/*設置center目標屬性值*/

view.center=CGPointMake(200,200);

}completion:^(BOOLfinished){

/*動畫執行結束回調*/

}];

動畫持續時間為0.3s。在animations代碼塊中定義目標屬性值。動畫結束后會回調completion代碼塊,可在動畫結束后繼續開始新的動畫,實現簡單的連續動畫效果。

2.

什么是隱式動畫和顯式動畫?正確答案:隱式動畫是UIKit動畫的基礎,是iOS中創建動態UI界面的最直接的一種方式。開發者通過直接設定UI元素的一些可見屬性的目標值,如frame、bounds、center、transform、alpha、backgroundColor、contentStretch等,即可自動生成屬性變化的過渡動畫。例如,設置視圖的目標位置為P1,即可自動生成從視圖當前位置移動到P1的平滑動畫。隱式動畫是一種默認動畫,動畫是線性的,可以滿足基本的需求,但對于一些復雜的動畫,如讓視圖沿曲線移動,隱式動畫就無能為力了,需要定義顯式動畫來實現。

例如,假設視圖view位于屏幕外,通過執行下面的隱式動畫,view可以平滑地移入當前視圖中央,動畫時間為0.5s,動畫結束時則回調可以緊接著進行其他的操作,如繼續進行下一個動畫等。

/*隱式動畫,視圖平滑移入當前視圖中央*/

[UIViewanimateWithDuration:0.5animations:^{

view.center=self.view.center;

}completion:^(BOOLfinished){

//動畫結束回調...

}];

顯式動畫不像隱式動畫那樣默認從一個初始狀態線性變化到目標狀態,而是需要顯式地定義完整的動畫流程,這樣略微復雜的同時會更加靈活,可以實現更加復雜的動畫效果。例如,隱式動畫只能實現直線平移效果,而顯式動畫可以顯式地定義任意的曲線路徑,讓視圖沿著曲線移動。簡單來說,顯式動畫就是要顯式地定義動畫對象,設置動畫對象的各個狀態和值,然后將動畫對象應用到視圖上,即可呈現動畫的效果。

例如,下面定義一個在x和y軸方向上(二維平面)不斷縮放的動畫對緣,動畫使視圖層先放大1.2倍,動畫結束后回到初始狀態,如此循環。應用的時候將該動畫對象添加到對應視圖的layer層上即可。

/*定義基本動畫對象(縮放動畫)*/

CABasicAnimation*animation=[CABasicAnimationanimationWithKeyPath:@"transformPath"];

/*設置動畫目標狀態,xy平面放大1.2倍*/

CATransform3DscaleTransform=CATransform3DMakeScale(1.2,1.2,1);

animation.toValue=[NSValuevalueWithCATransform3D:scaleTransform];

/*動畫持續時間0.5s*/

animation.duration=0.5;

/*動畫不斷循環重復*/

animation.repeatCount=HUGE_VALF;

/*自動逆動畫*/

animation.autoreverses=YES;

/*動畫結束移除之前動畫對視圖的影響,回到初始狀態*/

animation.removedOnCompletion=NO;

animation.fillMode=kCAFillModeForwards;

/*應用動畫*/

[view.layeraddAnimation:animationforKey:@"animationScaleKey"];

3.

隱式動畫的實現原理是什么?如何禁用圖層的隱式動畫?正確答案:在iOS程序開發中,有時僅僅改變了圖層或者視圖的一個動畫屬性(例如backgroundColor),就會發現屬性是平滑地過渡到目標值的,屬性值的改變產生了一個動畫效果,而實際上開發者并沒有顯式地使用動畫,這就是隱式動畫的作用。

隱式動畫指當更改視圖的非根圖層的可動畫屬性時,CoreAnimation自動決定如何并且何時去做動畫。動畫的執行時間取決于當前事務(CATransaction),而動畫類型取決于圖層行為。

CATransaction類是用來包含一系列屬性動畫集合的機制,任何用指定事務去改變可動畫屬性都不會立即發生變化,而是當事務提交的時候開始用一個動畫過渡到新值。CATransaction類沒有屬性或者實例方法,也不能用+alloc和-init方法創建,但是可以用+begin和+commit方法分別來入棧和出棧,這類似于UIView的+beginAnimations:context:和+commitAnimations方法。其次,還可以用+setAnimationDuration方法設置當前事務的動畫時間,或者+animationDuration方法來獲取值。

改變屬性是CALayer自動應用的動畫被稱為“行為”。當CALayer的屬性被修改的時候,它會調用actionForKey:方法,傳遞屬性的名稱。具體的實現原理分為以下幾步:

1)圖層會檢測其是否有代理,并且代理是否實現了CALayerDelegate協議指定的-actionForLayer:forKey方法。如果有,那么直接調用并返回結果。

2)如果圖層沒有代理,或者代理沒有實現-actionForLayer:forKey:方法,那么圖層會接著檢查包含屬性名稱對應行為映射的actions字典。

3)如果actions字典沒有包含對應的屬性,那么圖層接著在它的style字典搜索屬性名。

4)最后,如果在style字典中也沒有找到對應的行為,那么圖層將會直接調用定義每個屬性的標準行為的-defaultActionForKey:方法。

于是就可以解釋UIKit是如何禁用隱式動畫的:每個UIView都是其根圖層的代理,并且實現了-actionForLayer:forKey:方法,只不過返回nil,也就是不執行任何動畫。

除了在-actionForLayer:forKey:方法的實現中返回nil外,還可以通過CATransaction的方法+setDisableActions來打開或者關閉屬性的隱式動畫。使用+setDisableActions臨時取消隱式動畫的代碼如下:

-(void)viewDidLoad{

[superviewDidLoad];

_colorLayer=[CALayerlayer];

_colorLayer.bounds=CGRectMake(0,0,200,200);

_colorLayer.position=self.view.center;

_colorLayer.baekgroundeolor=[UIColorredColor].CGColor;

_colorLayer.delegate=self;

[self.view.layeraddSublayer:_colorLayer];

}

-(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event{

[CATransactionbegin];

//關閉隱式動畫

CATransaction.disableActions=YES;

CATransaction.animationDuration=5;

_colorLayer.backgroundColor=randomColor.CGColor;

[CATransactioncommit];

}

4.

CGAffineTransform和CATransform3D分別有什么作用?正確答案:CGAffineTransform被稱為“仿射變換”,它被定義在CoreGraphics框架中,主要用于在二維平面對視圖進行旋轉、縮放和平移。事實上,CGAffineTransform是一個可以和二維空間向量(如CGPoint)做乘法的3×2的矩陣。CGAffineTransform中“仿射”的意思是無論使用什么值的變換矩陣,圖層中平行的兩條線在變換之后仍然會保持平行。

CoreGraphics框架提供了一系列函數來創建CGAffineTransform實例,主要有以下幾種:

/*平移*/

CGAffineTransformMakeTranslation(CGFloattx,CGFloatty)

/*縮放*/

GAffineTransformMakeScale(CGFloatsx,CGFloatsy)

/*旋轉*/

CGAffineTransformMakeRotation(CGFloatangle)

UIView中的transform屬性或者CALayer中的affineTransform屬性都是CGAffineTransform類型,可以使用它們對視圖或者圖層進行仿射變換。此外,CoreGraphics框架還提供了一些可以進行混合變換的函數,能夠在一個變化的基礎上做更深層次的變換,甚至可以將兩個已經存在的變換矩陣進行合并。如果要做多次變換的操作,那么這些函數就會非常有用。下面用例子來演示一個包含縮放、旋轉和移動的變換,示例代碼如下:

-(void)viewDidLoad{

[superviewDidLoad];

_searchImageView=[[UIImageViewalloc]initWithFrame:CGRectMake(([UIScreenmainSereen].bounds.size:width-200)*0.5,([UIScreenmainScreen].bounds.size:height-200)*0.5,200,200)];

_searchImageView.image=[UIImageimageNamed:@"馬"];

[self.viewaddSubview:_searchImageView];

}

-(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event{

/*創建一個空的CGAffineTransform*/

CGAffineTransformtransform=CGAffineTransformIdentity;

/*縮放*/

transform=CGAffineTransformScale(transform,0.5,0.5);

/*旋轉*/

transform=CGAffineTransformRotate(transform,M_PI_4);

/*平移*/

transform=CGAffineTransformTranslate(transform,100,0);

_searchImageView.transform=transform;

}

CATransform3D是CoreAnimation結構體。和CGAffineTransform一樣,它也是一個矩陣。CATransform3D主要用來做更復雜的關于CALayer的3D操作。CoreAnimation提供了一系列方法來創建和組合CATransform3D類型的矩陣,這些函數和CGAffineTransform類似,只是多了一個z參數,并且旋轉函數除了angle之外還多出了x、y、z3個參數,這些參數分別決定了每個坐標軸方向上的旋轉。主要函數如下:

/*3D平移*/

CATransform3DMakeTranslation(CGFloattx,CGFloatty,CGFloattz)

/*3D旋轉*/

CATransform3DMakeRotation(CGFloatangle,CGFloatx,CGFloaty,CGFloatz)

/*3D縮放*/

CATransform3DMakeScale(CGFloatsx,CGFloatsy,CGFloatsz)

此外可以通過CATransform3D中的m34元素來控制3D變換的透視效果。m34元素主要用于按比例縮放X和Y的值來計算遠離視角的距離。m34的默認值是0,可以通過設置其為-1/d來應用透視效果,d代表了視角和屏幕之間的距離,d的值越小,透視效果越強,一般設置為500~1000。示例代碼如下:

-(void)viewDidLoad{

[superviewDidLoad];

_searchImageView=[UIImageViewalloc]initWithFrame:CGRectMake(([UIScreenmainScreen].bounds.size.width-200)*0.5,([UIScreenmainScreen].bounds.size.height-200)*0.5,200,200)];

_searchImageView.image=[UIImageimageNamed:@"馬"];

[self.viewaddSubview:_searchImageView];

/*創建一個空的CATransform3D*/

CATransform3Dtransform=CATransform3DIdentity;

/*設置m34元素,增強透視效果*/

transform.m34=-1.0/500.0;

/*3D旋轉變換*/

transform=CATransform3DRotate(transform,M_PI_4,0,1,0):

_searchImageView.layer:transform=transform;

}

5.

CATransition中過渡類型動畫有哪幾種type?正確答案:CATransition是CoreAnimation框架提供的轉場動畫類。開發者可以通過一組預定義的轉換或者定制的CIFilter實例來指定轉場效果。下面的代碼演示了當單擊tabBar按鈕時的界面切換動畫。

-(void)tabBar:(UITabBar*)tabBardidSelectItem:(UITabBarItem*)item{

CATransition*animation=[CATransitionanimation];

animation.duration=0.5:

/*指定效果*/

animation.type=@"reveal";

/*指定效果展示方向*/

animation.subtype=@"fromBottom";

[self.view.layeraddAnimation:animationforKey:nil];

}

其中的type屬性是一個NSString類型的字符串,指定了轉場動畫的類型。它有4個效果可供選擇:

1)fade:淡入淡出的過渡效果。對應常量kCATransitionFade。

2)moveIn:新視圖移動到舊視圖的上面。對應常量kCATransitionMoveIn。

3)push:新視圖將舊視圖推出窗口。對應常量kCATransitionPush。

4)reveal:舊視圖移開顯示下面的新視圖。對應常量kCATransitionReveal。

需要注意的是,以上4種效果都暴露在CATransition的.h頭文件中,可以安全使用。除此之外,還有一些效果屬于iOS私有的API,在使用這些效果后,應用在審核時有一定被拒絕的風險。這些效果包括:

1)cube:立方體效果。

2)oglFlip:翻轉效果。

3)suckEffect:收縮效果。

4)rippleEffect:水滴波紋效果。

5)pageCurl:向上翻頁效果。

6)pageUnCurl:向下翻頁效果。

7)cameraIrisHollowOpen:攝像頭打開效果。

8)cameraIrisHollowClose:攝像頭關閉效果。

6.

如何使用UIView動畫自定義過渡動畫?正確答案:CATransition雖然是一種對那些不太好做平滑動畫屬性的強大工具,但是它的缺點也很明顯,那就是提供的動畫類型太少了。除此之外還可以使用UIView提供的過渡動畫API。

+(void)transitionWithView:duration:optiotis:animations:completion:;

+(void)transitionFromView:toView:duration:options:completion:;

和CATransition一樣,UIView提供的過渡動畫類型仍然很少,其中options參數可以指定如下常量。

typedefNS_ENUM(NSInteger,UIViewAnimationTransition){

UIViewAnimationTransitionNone,

UIViewAnimationTransitionFlipFromLett,

UIViewAnimationTransitionFlipFromRight,

UIViewAnimationTransitionCurlUp,

UIViewAnimationTransitionCurlDown,

};

在實際開發中,有時CATransition和UIView提供的過渡效果并不能滿足項目需求,這時就必須考慮實現自定義的過渡動畫了。

過渡動畫的基礎原則就是對原始圖層外觀截圖,然后添加一段動畫,平滑過渡到圖層改變之后那個截圖的效果。CALayer的renderInContext:方法可以將當前圖層內容繪制成圖片,然后在視圖中顯示出來。如果將這個截屏視圖置于原始視圖之上,那么就可以遮住真實視圖的所有變化,于是就能通過簡單的UIView動畫API創建過渡效果。對當前視圖狀態截圖,然后在改變背景圖片的時候對截圖快速轉動并且淡出,示例代碼如下:

-(void)startCustomTransitionAnimation{

/*獲取截圖*/

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,YES,0);

[self.view.layerrenderInContext:UIGraphicsGetCurrentContext()];

UIImage*coverImage=UIGraphicsGetImageFromCurrentImageContext();

/*將截圖添加到主視圖*/

UIImageView*coverImageView=[[UIImageViewalloc]initWithImage:coverImage];

coverImageView.frame=self.view.bounds;

[self.viewaddSubview:coverImageView];

/*更換背景圖片*/

self.view.layer.contents=(id)[UIImageimageNamed:@"2"].CGImage;

/*添加動畫*/

[UIViewanimateWithDuration:1animations:^{

CGAffineTransformtransform=CGAffineTransformMakeScale(0.01,0.01);

transform=CGAffineTransformRotate(transfoma,M_PI_2);

coverImageView.alpha=0;

coverImageView.transform=transform;

}completion:^(BOOLfinished){

[coverImageViewremoveFromSuperview];

}];

}

效果如圖所示。

動畫過渡效果

7.

如何理解并使用CAKeyframeAnimation?正確答案:CAKeyframeAnimation即關鍵幀動畫,它是CAPropertyAnimation的一個子類,它作用于單一的屬性,但和CABasicAnimation不一樣的是,它不需要設置一個起始和結束的值,而是可以根據開發者提供的一連串隨意的值來做動畫。這些值就是關鍵幀,每幀之間的繪制將由系統自動完成。示例代碼如下:

-(void)startKeyframeAnimation{

CAKeyframeAnimation*animation=[CAKeyframeAnimationanimation];

/*指定需要做動畫的屬性*/

animation.keyPath=@"backgroundColor";

/*指定關鍵幀*/

animation.values=@[(id)[UIColorwhiteColor].CGColor,(id)[taColorreaColor].CGColor,(id)(id)[UIColorblueColor].CGColor,(id)[UIColorblackColor].CGColor,(id)[UIColorwhiteColor].CGColor];

/*指定關鍵幀的過渡時間*/

animation.keyTimes=@[@0,@0.2,@0.5,@0.7,@1];

animation.duration=5;

/*指定關鍵幀的過渡緩沖方式*/

animation.timingFunctions=@[[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunetionEaseInEaseOut],[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[self.view.layeraddAnimation:animationforKey:nil];

}

使用關鍵幀動畫需要注意下面3點:

1)注意到values數組中開始和結束的顏色都是白色,這是因為關鍵幀動畫并不能將當前值作為第一幀。動畫在執行后會立即跳轉到第一幀的值,然后在動畫結束的時候突然恢復到原始值。所以為了使動畫更加平滑自然,需要使用開始和結束的關鍵幀來匹配當前屬性的值。

2)除了使用values來指定關鍵幀以外,還可以使用其path屬性。它是CGPath類型,它可以用一種非常直觀的方式來定義動畫的運動序列。在做一些基于位置改變的動畫時,它非常有用。

@property(nullable)CGPathRefpath;

3)指定要做動畫的屬性并非只能是可動畫屬性(animatable),可以對子屬性甚至是虛擬屬性(不能直接使用)做動畫。例如,指定keyPath為transform.rotaion來做旋轉動畫。

8.

如何自定義UIViewController之間的轉場動畫?正確答案:在實際開發中,程序界面常常需要在不同的控制器視圖之間切換,常用的跳轉方式有push、pop、present和dismiss等。如果使用這些方式,那么系統會提供默認的動畫效果,例如當使用-pushViewController:animation:的時候會產生一個新視圖從右往左推開舊視圖的動畫效果。但是有時候希望跳轉方式能以其他的動畫效果展示,這時就需要自定義轉場動畫。

在開始自定義轉場動畫之前,有必要先了解幾個簡單的概念。

1)fromView和toView,在很多API中常常會有fromView和toView,ffomView表示當前視圖,即跳轉前的視圖,而toView代表跳轉后的視圖(或稱為跳轉的目標視圖)。

2)presentedViewController和presentingViewController,這也是一組相對的概念,presentedViewController表示被modal出的視圖控制器(或稱為跳轉的目標視圖控制器),而presentingViewController代表源視圖控制器。

3)UIViewControllerTransitioningDelegate協議用于為跳轉動畫提供實現了UIViewControllerAnimatedTransitioning協議的對象。

4)UIViewControllerAnimatedTransitioning協議主要用于控制動畫的展示時間和動畫展示邏輯。

5)UIViewControllerInteractiveTransitioning協議即交互式轉場動畫代理,這個協議主要用于交互式動畫。

6)UIViewControllerContextTransitioning協議即轉場動畫上下文協議,它的作用在于為動畫提供必備的信息。開發者不應該緩存任何關于動畫的信息,而是應該從轉場動畫上下文中獲取,這樣可以保證總是獲取到最新的、正確的信息。

要實現整個轉場動畫邏輯需要兩組必需的元素,其一是代表頁面跳轉關系的兩個控制器對象,其二是動畫執行邏輯。以下是實現動畫的步驟:

1)為源控制器和目標控制器分別設置一個遵守UIViewControllerAnimatedTransitioning協議的代理對象。當然也可以設置為同一個對象。

2)調用對應的跳轉方法。此時系統會自動請求動畫代理提供動畫邏輯對象。

下面的例子展示了一個自定義的跳轉動畫效果。

/*設置transitioningDelegate為當前控制器*/

-(void)startCustomControllerTransitionAniamtion1:(UITouch*)touch{

_touchPoint=[touchlocationInView:self.view];

TouchExampleController*VC=[TouchExampleControllernew];

vc.type=3;

vc.transitioningDelegate=self;

[selfpresentViewController:vcanimated:YEScompletion:nil];

}

/*當modal時,系統會自動調用此方法返回一個遵守UIViewControllerAnimatedTransitioning協議的對象*/

-(nullableid<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController*)presentedpresentingController:(UIViewController*)presentingsourceController:(UIViewController*)source{

TransitionAnimator*animator=[TransitionAnimatornew];

/*將單擊坐標傳過去,以確定動畫開始的點*/

animator.touchPoint=_touchPoint;

returnanimator:

}

/*在TransitionAnimator類實現中,實現UIViewControllerAnimatedTransitioning協議*/

@implementationTransitionAnimator

/*設置動畫時長*/

-(NSTimeInterval)transitionDuration:(nullableid<UIViewControllerContextTransitioning>)transitionContext{

return1;

}

/*設置動畫*/

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{

/*從上下文中獲取必需信息*/

UIView*fromV=[transitionContextViewForKey:

UITransitionContextFromViewKey];

UIView*toV=[transitionContextviewForKey:UITransitionContextToViewKey];

UIView*containerView=[transitionContextcontainerView];

/*將視圖添加到containerView中*/

[containerViewaddSubview:fromV];

[containerViewaddSubview:toV];

CGFloatscreenWidth=[UIScreenmainScreen].bounds.size.width;

CGFloatscreenHeight=[UIScreenmainScreen].bounds.size.height;

CGPointtempPoint=[containerViewconvertPoint:self.touchPointfromView:[transitionContextviewForKey:UITransitionContextFromViewKey]];

CGRectrect=CGRectMake(tempPoint.x-1,tempPoint.y-1,2,2);

/*使用UIBerizerPath繪制動畫的開始路徑和結束路徑*/

UIBezierPath*startPath=[UIBezierPathbezierPathWithOvalInRect:reet];

UIBezierPath*endPath=[UIBezierPathbezierPathWithArcCenter:containerView.centerradius:sqrt(screenHeight*screenHeight+screenWidth*screenWidth)startAngle:0endAngle:M_PI*2clockwise:YES];

/*設置maskLayer*/

CAShapeLayer*maskLayer=[CAShapeLayerlayer];

maskLayer.path=endPath.CGPath;

toV.layer.mask=maskLayer;

/*設置動畫*/

CABasicAnimation*animation=[CABasicAnimationanimationWithKeyPath:@"path"];

animation.delegate=self;

animation.fromValue=(id)startPath.CGPath;

animation.toValue=(id)endPath.CGPath;

anim

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論