[iOS]UIView Block 애니메이션 사용하기
아이폰 UIKit 기반으로 개발하면 objective-c로 개발할 수 밖에 없다. 2년 아이폰 개발을 했지만 [] 형태의 언어 문법의 장점을 정말 모르겠다. 손도 많이 가고 코드도 길어진다. 불행중 다행인게 iOS 4.0부터 Block 함수를 쓸 수 있게 되어 프로세스 단위로 코딩이 좀 더 깔끔하게 짤 수 있게 되었다. Block 프로그래밍은 여러가지고 꽤 장점이 많기 때문에 다양하게 응용해볼 필요가 있다. 여기서는 UIView 애니메이션에서 제공하는 블록 함수를 사용해보는 것으로 블록 프로그래밍에 대해서 맛보기 해본다.
전에 UIView에서 Animation기능은 너무 불편했다. 아래는 UIView 애니메이션의 인터페이스이다.
@interface UIView(UIViewAnimation) + (void)beginAnimations:(NSString *)animationID context:(void *)context; // additional context info passed to will start/did stop selectors. begin/commit can be nested + (void)commitAnimations; // starts up any animations when the top level animation is commited // no getters. if called outside animation block, these setters have no effect. + (void)setAnimationDelegate:(id)delegate; // default = nil + (void)setAnimationWillStartSelector:(SEL)selector; // default = NULL. -animationWillStart:(NSString *)animationID context:(void *)context + (void)setAnimationDidStopSelector:(SEL)selector; // default = NULL. -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context + (void)setAnimationDuration:(NSTimeInterval)duration; // default = 0.2 + (void)setAnimationDelay:(NSTimeInterval)delay; // default = 0.0 + (void)setAnimationStartDate:(NSDate *)startDate; // default = now ([NSDate date]) + (void)setAnimationCurve:(UIViewAnimationCurve)curve; // default = UIViewAnimationCurveEaseInOut + (void)setAnimationRepeatCount:(float)repeatCount; // default = 0.0. May be fractional + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses; // default = NO. used if repeat count is non-zero + (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState; // default = NO. If YES, the current view position is always used for new animations -- allowing animations to "pile up" on each other. Otherwise, the last end state is used for the animation (the default). + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache; // current limitation - only one per begin/commit block + (void)setAnimationsEnabled:(BOOL)enabled; // ignore any attribute changes while set. + (BOOL)areAnimationsEnabled; @end
이 인터페이스로 만들게 될때 콜백함수가 여러개 붙게 되면 프로세스를 따라가기가 얼마나 불편한지 모른다.
iOS 4.0부터 지원하는 UIView의 Block 애니메이션 인터페이스는 다음과 같다.
@interface UIView(UIViewAnimationWithBlocks) + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // delay = 0.0, options = 0 + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // delay = 0.0, options = 0, completion = NULL + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // toView added to fromView.superview, fromView removed from its superview @end
이 인터페이스를 사용하면 아래와 같이 만들 수 있다.
button.transform=CGAffineTransformMakeScale(0.1, 0.1);
button.alpha = 0;
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
button.transform=CGAffineTransformMakeScale(1, 1);
button.alpha = 1;
}
completion:^(BOOL finished){
button.transform=CGAffineTransformIdentity;
}]; 애니메이션 처리 후처리를 블로내에서 처리할 수 있게 되어 코드가 전보다 훨씬 간결해진다.
이것을 사용해 버튼을 누르면 이미지가 확대되고 이 이미지를 누르면 없어지는 코드를 만들어보았다.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(self.window.frame.size.width * 0.5 - 50, 40, 100, 30)];
[button setTitle:@"터치" forState:UIControlStateNormal];
[button addTarget:self action:@selector(_touched:) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:button];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (void)_touched:(id)sender
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:@"iu.png"] forState:UIControlStateNormal];
[button setFrame:CGRectMake(self.window.frame.size.width * 0.5 - 100, self.window.frame.size.height * 0.5 - 110, 200, 220)];
[button setTitle:@"감추기" forState:UIControlStateNormal];
[button addTarget:self action:@selector(_touched2:) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:button];
button.transform=CGAffineTransformMakeScale(0.1, 0.1);
button.alpha = 0;
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
button.transform=CGAffineTransformMakeScale(1, 1);
button.alpha = 1;
}
completion:^(BOOL finished){
button.transform=CGAffineTransformIdentity;
}];
}
- (void)_touched2:(id)sender
{
UIView *view = (UIView*)sender;
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
view.transform=CGAffineTransformMakeScale(0.1, 0.1);
view.alpha = 0;
}
completion:^(BOOL finished){
[view removeFromSuperview];
}];
}음... 하지만 저 애니메이션을 보여주기 위해서 저렇게 많은 코드를 써야한다니.... ㅡㅡ
UIKit 기반 iOS 앱 개발은 암튼 코딩이 피곤하다. ㅎㅎ
다음 글을 보면 Block 프로그래밍에 대해서 더 공부할 수 있겠다. 기존에 Selector만 넘겨주는 방식을 Block으로 바꾸면 훨씬 코드가 간결해질 수 있으므로 잘 활용해봐야겠다.
Block Programming Guide in ios : http://blog.dbinsight.net/4
^Block 사용으로 UIImagePickerController 좀더 편하게 사용하기 – 게으른자를 위하여 http://www.iosappdev.co.kr/iosappdev/?p=1409
GCD와 Block을 이용해서 비동기 방식으로 URL 이미지 로드하기 http://blog.saltfactory.net/97
- [문씨의 강좌] 멀티스레딩3 <Grand Central Dispatch> http://
lab.smoon.kr/74
보면 알겠지만 블록이 결국 closure라고 생각하면 된다는...
글쓴이 : 지돌스타(http://blog.jidolstar.com/831)
'iOS' 카테고리의 다른 글
| [iOS]UITextField에 한칸 공백 입력만 허용하기 (0) | 2012/09/06 |
|---|---|
| [iOS]NSObject, UIAlertView, UIActionSheet에 Block 함수 적용하기. GCD도 언급 (0) | 2012/08/25 |
| [iOS]UIView Block 애니메이션 사용하기 (0) | 2012/07/26 |
| [Cocos2D for iPhone]Xcode 4에 설치하고 간단한 프로젝트 만들어보기 (1) | 2012/07/25 |
| [iOS]앱 배포시 "An error occurred uploading to the iTunes Store" 에러 대처 방법 (0) | 2012/05/19 |
| Xcode 4에서 라이브러리 파일(*.a)가 ignore 처리되어 SVN에 등록되지 않을때 해결방법 (1) | 2012/03/29 |
BlockAnimationTest.zip
