[iPhone Dev] UI Transition Animation Tip – 뷰를 작게 했다가 커지게 하면서 나타나게 할 때

2 Comments

요즘은 치매끼가 있는지.. 예전에 삽질해서 처리한 것에 대해서 또 반복해서 삽질하고 있고 또 같은 방법으로 해결하고 있네요 -_-; 각설하고 본문으로 들어가면..

Camera+의 경우는 각 UI들이 transition animation을 통해서 타나나거나 사라집니다. 최근에 2.2 업데이트에서도 transition animation이 더 추가된 것에 대해서 TUAW에서 다룰 만큼 ( Camera + 2.2 adds Clarity feature, UI improvements, more , 워낙 유명하고 Top 10에 머물러 있어 그럴 수도 있겠지만).

Transition Animation 중에 하나로 뷰를 나타나게 할 때, 가운데 작은 뷰에 알파를 0.1 정도 준 상태에서, 원래 크기로 만들고 알파도 1.0으로 해주는 (나름 패드 같은데서 보면 좋아보이는) transition을 생각할 수 있을 것입니다.

 

문제 점 – view frame으로 animation을 처리할 때

[1] 간단하게 생각하면  animation 전에 view frame을 작게 하고 알파도 낮춘 다음에 animation commit에서 frame도 돌려놓고 알파도 돌리면 될 것은데..

sub view들의 크기가 변하지 않는 문제가 생길 것입니다.

[2] 그래서 아래와 같이 base view에 autoresizeSubviews를 YES로 해주고

self.view.autoresizesSubviews = YES;

[3] Sub view들의 autoresizingMask를 처리해주고 시도 해 볼 것입니다.

self.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;

[4] 하지만.. 문제는 float 때문인지.. sub view들의 비율이 맞지가 않습니다. (패드 같은데서는 많이 어긋나는 경우도 있죠)

 

해결 책

View frame을 이용히지않고 view의 transform을 이용해서 축소했다가 확대하면 코드도 짧고 깔끔하게 처리됩니다.

물론 autoresizeSubviews나 autoresizingMask는 손댈 필요가 없겠죠.

[1] Animation 전에 대상 뷰의 transform을 아래와 같이 축소 시키고

view.transform = CGAffineTransformMakeScale(0.1, 0.1);

[2] Animation에서 다음과 같이 복구를 시켜주면 깔끔하죠

view.transform = CGAffineTransformMakeScale(1.0, 1.0);

[iPhone Dev] XCode에서 실행할 때마다 올라오는 Debug Area 및 좌측 Navigator 조절하기

No Comments

실행을 하면, 항상 아래 쪽의 Debug Area (콘솔창같은)가 올라오고, 좌측의 Navigator가 바뀝니다.

( -_-; 항상 Shift + Cmd + Y로 콘솔 내리기가 짜증나죠)

설정을 찾아보니 아래와 같이 “Behaviors”에서 Run 시의 행동을 설정할 수 있었습니다.

즉, 아래 “Run generates output”에서 “Show navigator”와 “Show Debug Area”의 체크를 풀어 주면 됩니다.

[iPhone Dev] NSDictionary, NSArray 등의 저장에 대해

No Comments

NSUserDefaults를 이용해서 NSString 기반으로 앱의 데이터를 저장하는 것은 손쉽지만, NSDictionary나 NSArry 등의 데이터를 저장하기는 불편할 것입니다.

NSPropertyListSerialization을 이용하는 방법을 주로 사용했었는데요, NSDictionary의 writeToFile:automatically과 dictionaryWithContentsOfFile: 을 이용해서 좀 더 직관적으로 하는 것도 좋을 것 같아서 포스팅 해봅니다.

 

[1] NSDictionary의 writeToFile:automatically과 dictionaryWithContentsOfFile: 이용

저장할 때는 writeToFile:automatically을 불러올 때는 dictionaryWithContentsOfFile: 을 이용하면 될 것입니다.

그리고 NSString의 stringByExpandingTildeInPath을 이용해서 Documents의 path도 쫌 더직관적으로 얻어 오면 다음과 같은 코드가 만들어질 것입니다.
[저장하기]

-(void)saveDic:(NSMutableDictionary*)aDic ForKey:(NSString*)aKey {
if( aDic == nil || aKey == nil ) {
return;
}

NSString* dataPath = [[NSString stringWithFormat:@"~/Documents/%@", aKey] stringByExpandingTildeInPath];

[aDic writeToFile:dataPath atomically:YES];

}

 

[불러오기]

-(NSMutableDictionary*)loadDicForKey:(NSString*)aKey {
if( aKey == nil ) {
return nil;
}

NSString* dataPath = [[NSString stringWithFormat:@"~/Documents/%@", aKey] stringByExpandingTildeInPath];

return [NSMutableDictionary dictionaryWithContentsOfFile:dataPath];
}

 

[사용 예]

NSPropertyListSerialization 의 사용에도 마찬가지지만, (실수에 의한) memory leak을 막기 위해서 데이터를 가지고 있는 object는 property로 처리하는 것이 좋은 것 같습니다.

// dictionaryWithContentsOfFile 이용
NSString* testKey = @"testKey";

self.dataDic = [self loadDicForKey:testKey];

if( self.dataDic ) {
NSLog(@"testKey (first): %@", self.dataDic);
}

[self.dataDic setObject:[NSArray arrayWithObjects:@"a", @"b", @"c", nil] forKey:@"abc"];

[self saveDic:self.dataDic ForKey:testKey];
self.dataDic = nil;

self.dataDic = [self loadDicForKey:testKey];

if( self.dataDic ) {
NSLog(@"testKey (second): %@", self.dataDic);
}

[2] NSPropertyListSerialization 이용

아래 코드에 주석으로 표기 했지만, propertyListFromData:mutabilityOption:format:error: 이나 dataFromPropertyList:format:error: 등은 곧 decprecate될 것이라고 하니 대체되는 method를 사용해야할 것입니다.

그리고 , [1]에서도 이야기 했지만, 데이터를 받는 객체는 property로 처리해줘야 memory leak을 깔끔하게 없앨 수 있겠죠.

 

[저장 및 불러오기]

 

-(NSMutableDictionary*)restoreDataForKey:(NSString*)aKey {

if( aKey == nil ) {
return nil;
}

NSString *finalPath = nil;

NSData *plistData;
NSError *error;
NSPropertyListFormat format;

// normal
finalPath = [self getFilePathForkey:aKey];
plistData = [NSData dataWithContentsOfFile:finalPath];

NSMutableDictionary* tempDic = nil;
if( plistData ) {
/*
// propertyListFromData will be deprecated soon.
dataDic = [NSPropertyListSerialization propertyListFromData:plistData
mutabilityOption:NSPropertyListMutableContainers
format:&format
errorDescription:&error];
*/
tempDic = [NSPropertyListSerialization propertyListWithData:plistData options:NSPropertyListMutableContainers format:&format error:&error];

}

if(tempDic == nil) {
tempDic = [[[NSMutableDictionary alloc] init] autorelease];
}

return tempDic;
}

-(void)storeData:(NSMutableDictionary*)aDic ForKey:(NSString*)aKey {

if( aDic == nil || aKey == nil ) {
return;
}

NSString *finalPath = nil;
NSData *xmlData;
NSError *error;

// normal
if(aDic != nil ) {

finalPath = [self getFilePathForkey:aKey];

/*
dataFromPropertyList will be deprecated soon.
xmlData = [NSPropertyListSerialization dataFromPropertyList:aDic
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
*/

xmlData = [NSPropertyListSerialization dataWithPropertyList:aDic format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];

if(xmlData) {
//NSLog(@"No error creating XML data.");
[xmlData writeToFile:finalPath atomically:YES];
}
else {
NSLog(@"%@", error);
[error release];
}
}
}

 

[사용 예]

// NSPropertyListSerialization 이용
testKey = @"testKey2";
self.dataDic2 = [self restoreDataForKey:testKey];
if( self.dataDic2 ) {
NSLog(@"testKey2 (first): %@", self.dataDic2);
}

[self.dataDic2 setObject:[NSArray arrayWithObjects:@"aa", @"bb", @"cc", nil] forKey:@"aabbcc"];

[self storeData:self.dataDic2 ForKey:testKey];

self.dataDic2 = nil;

self.dataDic2 = [self restoreDataForKey:testKey];

if( self.dataDic2 ) {
NSLog(@"testKey2 (scond): %@", self.dataDic2);
}

[iPhone Dev] Camera+ 팀의 FX 만드는 과정 공개 – 개발자와 디자이너가 밀착해야 하는 이유!

No Comments

Camera+ 는 (이 글을 쓰는 순간에도) 미국 유료 전체 순위 5위에 꾸준히 머물러 있습니다.

Camera+는 기능도 기능이지만 UI가 너무 매력적이어서 자주 거론하고 배울려고 하고 있습니다.

글을 본지는 조금 되었는데, 너무 좋아서 소장하고 있다가 포스팅합니다. ^^;;

 

(특히 iPhone에서는) 개발자와 디자이너가 (또 기획자가) 긴밀하게 개미처럼 소통해야하는지 느끼게 하는 글인 것 같습니다.

(베르나르의 소설 개미에서 개미들은 더듬이를 통해서 생각을 완전 공유한다고 합니다. )

 

Creating a Camera+ effect

이 글은 Camera+를 개발한 팀에서 FX 효과를 어떻게 만들었는지 9단계에 걸친 자세한 설명과 동영상, 코드 예제까지 아주 친절하게 썼습니다.

과연 저렇게 자신들의 노하우를 공개할 수 있을까? 라는 생각이 들게 합니다. 그만큼 자신감이 있고 또 공유를 통한 더 발전을 꾀하기 위해서겠죠.

아래와 같은 멋진 FX를 만드는 과정입니다 (자세한 것은 원문을 보시고 여기는 간단히 정리만 하겠습니다)

 

Step 1: Concept

일반 사진 중에서 멋지게 잘 찍은 (또는 오래되어서 그 자체로 멋진 FX가 가미된) 사진을 선택합니다.

 

Step 2: First draft of the formula

포토샵으로 iPhone의 사진을 이용해서 color, contrast, tone등을 조절하면서 Step1에서 선택한 사진과 유사한 효과를 낼 수 있는 공식을 도출해 봅니다.

 

Step 3: Testing

공식을 만들고 나면 수백 장의 iPhone 사진으로 테스트를 해봅니다. 그리고 결과가 좋지 않으면 다시 Step 2로 돌아갑니다.

 

Step 4: In-app testing

코드로 Draft 버전의 FX code를 만들어서 App 내에서 테스트를 해봅니다.

 

Step 5: Wolfgang creates textures

이 부분에서 저도 좋은 아이디어를 얻었는데요, 포토샷을 이용한 공식 이외에도 이미지 위에 올린 Texture Layer를 만들어 봅니다.

(비디오를 보시면 바로 이해가 가십니다)

 

Step 6: Finalizing the FX formula in Photoshop

Step5의 texture를 적용하면서 포토샵의 공식을 조정해서 최종 본을 만들어 냅니다.

 

Step 7: Karl codes magic

FX로 사용할 코드를 만들어 냅니다.

 

Step 8: Karl optimization

코드 최적화를 통해서 성능 최적화를 합니다.

(이 부분은 사진 관련 앱을 해본 저로써는 정말 동감하는 부분입니다)

 

Step 9: Ship it!

최종으로 앱에 반영하겠죠. ㅜㅜ 예제 코드도 첨부해주는 Camera+에 감사할 따름이죠.

 

[후기]

이와 같은 과정은 디자이너 혼자, 개발자 혼자, 또는 같이라도 긴밀한 협업 없이는 힘들 것입니다.

포토샵으로 공식을 만들고, 수백장의 아이폰 사진으로 테스트하고, 코드로 만들고, 또 테스트하고, Texture를 만들고, 또 공식을 보정하고, 또 테스트하고, 코드를 만들고, 최적화하고…

고, 고, 고,….. 그런 긴 과정에서 하나의 멋진 FX를 만들어내고 있습니다.

Camera+를 보면 딱 짚어서 말하기 힘든 UI의 부드러움과 사용의 편리함을 보면, 그들의 이런 노력과 열정은 앱 전반에 있는 것 같습니다.

(e.g. Indicator 하나를 돌릴 때도 indicator가 작아진 상태에서 커지는 애니메이션을 통해서 indicator가 타나난다든지..)

 

 

 

 

 

 

 

 

[iPhone Dev] Color – N Screen? No. N Device. (미려한 UI)

No Comments

iPhone, iPad, 갤스, 갤탭 등으로 N Screen이 많이 이야기 되어지고 있습니다.

발상의 전환인 앱이 하나 있네요. Color ( http://itunes.apple.com/us/app/color/id427763573?mt=8 ) 입니다.

color app

Color는 최초 앱을 시작하면 자신이 그룹을 하나 만들 수 있고,

위치 기반으로 금방에서 찍은 사진들을 아주 미려한 UI로 함께 보여줍니다.

사진에 댓글도 달 수 있고, 라이크도 보낼 수 있습니다. 무엇 보다도 간단하게 주위의 사진들을 볼 수 있어서 너무 좋네요.

(테스트를 해보는 중에도 주위 사무실에서 사진들이 막 올라오네요 :) )

 

UI도 배울게 많은 것 같습니다 (Camera+ UI를 처음 접했을 때의 감동이었습니다)

 

 

Ref: http://i.tuaw.com/2011/03/24/dreams-teams-and-the-color-app/

 

 

Older Entries