보관물

Posts Tagged ‘Xcode’

XCode에서 SCM(SVN)을 사용할 때를 위한 팁…

XCode와 SVN이 잘 궁합이 맞지 않는 것 처럼 느껴질 때가 많습니다.
그래서, 이런 저런 궁리를 하면서 찾은 정보를 아래 지속적으로 업데이트하고 있습니다. 물론, SVN에 대해 전체적인 기능을 모두 알고 계신 분들은 필요 없으리라 생각됩니다.
그러나, 간단하게 처리하는 경우 활용할 수 있어 공유합니다. (혹시, 모르니 아래 작업을 하실 경우 안정된 소스는 반드시 백업 후 진행하세요.)

* SVN 관련 팁 모음

XCode-Repositories과 SVN을 이용해서 소스 형상관리를 하는 경우 상황에 따라 update나 commit이 안되는 경우가 발생합니다.
이런 경우에 터미널 명령을 이용해서 대처하는 방안을 정리해 보았습니다.
문제가 되는 파일이 중요한 파일인 경우 백업 후 update를 하는 것이 좋겠습니다. (아래 내용은 필요에 따라 누구나 내용 변경하셔도 됩니다.)

* 상황별 조치 *
상황 1. XCode Organizer에서 update 가 안되는 경우
– 터미널에서 진행
1) 터미널에서 해당 폴더로 이동한다.
2) svn update 실행. -> 양쪽 모두를 수용하는 경우는 resolved(r)을 입력.

상황 2. svn commit 이 안되는 경우
– 터미널에서 진행
1) 터미널에서 해당 폴더로 이동한다.
2) svn commit 실행.
> 에러 발생하는 경우. SVN_EDITOR 설정이 필요한 경우.
export SVN_EDITOR=/usr/bin/vim 설정
svn commit 실행
— vi editor에서 변경내용 확인 후 :q로 빠져나오면 다음 액션 메시지 보임. continue로 계속 진행

* ignore 패턴 넣기 *

1. 개별적으로 넣기
svn의 무시하는 패턴을 넣는 방법
svn propset svn:ignore [pattern] [target]
예) xcuserdata 를 무시하기 위해서 현재 xcuserdata를 가지고 있는 폴더 인 경우
svn propset svn:ignore xcuserdata . <- target인 .을 빼면 안 됩니다.
svn propset -R svn:ignore xcuserdata . <- 하위 폴더 모두를 무시할 경우 -R 옵션
참고] XCode4 이상 버전에서는 [ProjectName].xcodeproj/xcuserdata/* 와 [ProjectName].xcodeproj/project.xcworkspace/xcuserdata/* 를 무시해야 합니다.

2. 글로벌 영역에 넣기
1) 자신의 홈폴더의 .subversion/config 파일을 에디터에서 오픈합니다.
2) .subversion/config 파일의 global-ignores 항목에 무시할 패턴을 넣습니다.
예) global-ignores = *.o *.lo build xcuserdata .DS_Store
3) 파일 저장 후 다시 Check-In 작업을 수행합니다.

참고로 찾은 .svn 삭제 방법입니다.
[원문] http://goo.gl/fqq5s
[내용]
토토이즈 SVN을 사용하다 보면, .svn 디렉토리를 삭제가 필요할 때가 있습니다.
프로그램을 짧가 하다가, 쉘에서 아주 간단하게 처리하는 방법이 있군요.

]$ find . -name .svn -print0 | xargs -0 rm -rf

pint0와 xarts-0 의 0는 모두 숫자 0(Zero) 입니다. 서브디렉토리까지 알아서 찾아 가면서
모두 삭제해 줍니다. ^^

Advertisements
카테고리:iPhone-iPad, Objective-C 태그:, , ,

XCode에서 정적라이브러리를 사용할 때 기본적으로 해야할 일.

XCode에서 정적 라이브러리를 사용하는 경우가 있습니다. 이런 경우 정적 라이브러리를 가져오는 프로젝트에서 해야 하는 기본적인 세가지 설정은 아래와 같습니다.

1. LinkBinary With Libraries에 정적 라이브러리 추가해 주기

2. Build Setting의 Header Search Paths와 Library Search Paths에 경로 추가하기

3. Build Setting의 Other Linker Flags에 -all_load -ObjC 설정 추가하기

이상 세가지 작업을 해 주면 정적라이브러리를 가져와서 사용할 수 있습니다.

 

* Device, Simulator 구분 없는 library 만들기

libtool -static Release-iphoneos/{libname}.a Release-iphonesimulator/{libname}.a -o {만들 libname}.a

iOS에서 애니메이션을 사용해 보자. (Core Animation)

최근에 Core Animation에 대해서 숙지하는 시간을 가졌습니다. 단순히 컨트롤이나 간단한 이미지에 대한 애니메이션 기능이라는 것은 알고 있었지만, 나중에 필요할 때에 찾아서 하면 되겠지라고 생각하고 있었는데, 마침 시간이 좀 있어서 정리를 해 보았습니다.
내용을 보면서 느낀 점은 Core Animation의 기능을 만드는 것은 마치 프리젠테이션 툴(파워포인트, 키노트 등)에서 오브젝트 애니메이션을 만드는 것과 비슷하다는 생각을 했습니다. 오브젝트를 움직이는 것도 중요하지만 잘 만들어진 애니메이션은 지나치지 않으면서도 꼭 필요한 곳에 적절하게 사용되는 것이 중요할 거라 생각되네요.

그럼 지금부터 간단한 설명과 효과에 대한 소스코드를 공유해 보려 합니다.

Core Animation을 이용하기 위한 기본적인 클래스는 ‘CAAnimation’ 입니다.. 그리고, CAAnimation에서 파생된 클래스가 아래와 같습니다.

  • CABasicAnimation:기본적인 애니메이션.(CAPPropertyAnimation의 파생클래스)
  • CAKeyframeAnimation:키프레임 애니메이션.(CAPPropertyAnimation의 파생클래스)
  • CATransition:레이어 전체에 대한 전환 효과.
  • CAAnimationGroup:여러 애니메이션을 같이 실행.

Core Animation classes and protocol

1. CABasicAnimation
CABasicAnimation은 레이어(CALayer)에 대해서 기본 애니메이션과 싱글 키프레임 애니메이션을 제공합니다.
아래 몇가지 프로퍼티를 가지고 있습니다.

  • fromValue: 애니메이션의 시작값
  • byValue: 애니메이션의 중간값
  • toValue: 애니메이션의 끝값

그럼 예제 소스를 하나 만들어 보겠습니다. 본 문서에서 예제들은 모두 뷰컨트롤러의 적당한 위치(viewDidLoad 등…)에 아래 소스를 넣어주면 됩니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 40, 40);
    layer1.position = CGPointMake(0, 160);
    layer1.cornerRadius = 20;
    layer1.backgroundColor = [UIColor blackColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGPoint pStart = CGPointMake(0, 160);
    CGPoint pEnd = CGPointMake(160,0);
    
    /* 애니메이션 작성 */
    CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"position"];
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    ani.fromValue = [NSValue valueWithCGPoint:pStart];
    ani.toValue = [NSValue valueWithCGPoint:pEnd];
    
    ani.repeatCount = HUGE_VAL;
    ani.duration = 10.0;
    [layer1 addAnimation:ani forKey:@"position"]; // 애니메이션을 원하는 레이어에 설정합니다.

위 소스를 통해 간단한 애니메이션을 구현할 수 있습니다. 검정색 원이 왼쪽 아래에서 오른쪽 위로 올라오는 것을 볼 수 있습니다. 위 소스의 애니메이션 작성 부분에서 아직 설명하지 않은 것은 세가지가 있습니다. timingFunction, repeatCount 그리고 duration 입니다. repeatCount와 duration은 이름과 같이 몇번 반복할 것인지와 애니메이션이 일어나는 시간을 설정하는 것 입니다.
timingFunction은 애니메이션이 일어나는 타이밍을 설정합니다. 타이밍 설정은 아래 네가지를 이용하여 설정할 수 있습니다.

  • kCAMediaTimingFunctionLinear : 일정한 속도로 재생
  • kCAMediaTimingFunctionEaseIn : 처음에 천천히 시작
  • kCAMediaTimingFunctionEaseOut : 마지막에 천천히 종료
  • kCAMediaTimingFunctionEaseInEaseOut : 천천히 시작하고 마지막에 다시 천천히 종료

이제 간단하게 객체를 이동하는 수준의 애니메이션을 작성할 수 있습니다.
이동 이외에도 Animation KeyPath의 동작은 아래와 같은 것도 있습니다.

2. CAKeyframeAnimation
키프레임 애니메이션을 만들어줍니다. 풀어서 얘기하면 정형적이지 않은 여러곳을 이동하는 프레임을 CGPathRef를 이용하여 설정하고, 그 위치를 특정 레이어가 이동하는 것 입니다.
기본적으로 사용하는 프로퍼티는 path, rotationMode가 있습니다.

간단한 예제를 보겠습니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 20, 20);
    layer1.position = CGPointMake(200, 200);
    layer1.cornerRadius = 10;
    layer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGMutablePathRef path1 = CGPathCreateMutable();
    CGPathMoveToPoint(path1,NULL,layer1.position.x, layer1.position.y);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 200);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x + 150, layer1.position.y + 150);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 0);
    
    /* 애니메이션 작성 */
    CAKeyframeAnimation *moveAni1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    moveAni1.path = path1;
    moveAni1.rotationMode = kCAAnimationRotateAuto;
    moveAni1.duration = 5.0;
    [layer1 addAnimation:moveAni1 forKey:@"position"]; // 애니메이션을 원하는 레이어에 설정합니다.

fromValue, toValue를 여러 포인트를 지정하는 path로 변경하고, 방향이 바뀌는 것에 대응하는 rotationMode를 제외하면 이전에 기본 애니메이션과 큰 차이는 없습니다.

3. CATransition
레이어가 전환되는 것을 처리하는 애니메이션 클래스입니다.
기본적으로 사용하는 프로퍼티는 아래와 같습니다.

  • type : 전환 애니메이션 종류.
  • subtype : 전화 애니메이션 방향.
  • duration : 애니메이션 시간.

간단한 예제를 통해 알아 보겠습니다.


    /* 전환 레이어 생성 */
    CALayer *layer4 = [CALayer layer];
    layer4.bounds = CGRectMake(0, 0, 320, 480);
    layer4.position = CGPointMake(0, 0);
    layer4.anchorPoint = CGPointMake(0, 0);
    layer4.backgroundColor = [UIColor blueColor].CGColor;
    [self.view.layer addSublayer:layer4];

    /* 전환 애니메이션 생성 */
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionReveal;
    transition.subtype = kCATransitionFromTop;
    transition.duration = 2.0;
    transition.delegate = self;
    [layer4 addAnimation:transition forKey:nil];

type에 설정되는 속성은 네가지입니다.

  • kCATransitionFade : 레이어를 바로 표시
  • kCATransitionMoveIn : subtype에 설정된 방향으로 진행하며 나타남. 이전에 있던 레이어 위로 나타남
  • kCATransitionPush : subtype에 설정된 방향으로 진행하며 나타남. 이전에 있던 레이어를 밀어냄
  • kCATransitionReveal : 희미한 상태에서 서서히 나타냄

subtype에 설정되는 속성은 네가지가 있습니다.

  • kCATransitionFromRight : 오른쪽 방향에서 들어옴.
  • kCATransitionFromLeft : 왼쪽 방향에서 들어옴.
  • kCATransitionFromTop : 아래에서 위로 올라옴. (왜? 테스트 결과 그렇게 됨.)
  • kCATransitionFromBottom : 위에서 아래로 내려옴.??

4. CAAnimationGroup
여러 애니메이션을 동시에 실행하는 경우 사용합니다. 예를 들면, 사진을 삭제하면 작아지면서 쓰레기통으로 이동하는 것에서 CABasicAnimation을 통해 작아지면서, CAKeyframeAnimation을 통해 이동하는 것으로 처리가 가능합니다. 마지막에 쓰레기통이 흔들리는 것은 Delegate설정을 한 후에 animationDidStop에서 처리해 주면 됩니다.
역시, 예제를 통해 알아보겠습니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 20, 20);
    layer1.position = CGPointMake(200, 200);
    layer1.cornerRadius = 10;
    layer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGMutablePathRef path1 = CGPathCreateMutable();
    CGPathMoveToPoint(path1,NULL,layer1.position.x, layer1.position.y);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 150);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x + 100, layer1.position.y + 100);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 0);
    
    /* 이동 애니메이션 작성 */
    CAKeyframeAnimation *moveAni1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    moveAni1.path = path1;
    moveAni1.rotationMode = kCAAnimationRotateAuto;
    moveAni1.duration = 5.0;
    
    /* 스케일 애니메이션 작성 */
    CABasicAnimation *scalAni1 = [CABasicAnimation animationWithKeyPath:@"transform"];
    scalAni1.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    scalAni1.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
    scalAni1.duration = 5.0;
    
    /* 투명 애니메이션 작성 */
    CABasicAnimation *opacityAni1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAni1.fromValue = [NSNumber numberWithFloat:1.0];
    opacityAni1.toValue = [NSNumber numberWithFloat:0.1];
    opacityAni1.duration = 5.0;
    
    /* 애니메이션 그룹 작성 */
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = [NSArray arrayWithObjects:moveAni1, scalAni1, opacityAni1, nil];
    group.duration = 5.0;
    
    [layer1 addAnimation:group forKey:nil]; //레이어에 그룹애니메이션 적용

그룹 애니메이션은 animations속성에 NSArray타입의 여러 애니메이션을 적용해 주는 것 만으로 애니메이션 동작이 가능합니다.

이상 CAAnimation의 기본적인 동작에 대해서 알아보았습니다. 간단한 앱내의 컨트롤들의 효과는 가능해 보이며, 재미있는 앱을 만들어 내는데 양념 역할을 충분히 할 수 있을 거라 생각합니다.
하지만, 처음에도 언급했던 것 처럼 지나친 애니메이션 사용은 사용자에게 피로감을 줄 수 있으니 잘 기획되어서 사용 해야겠습니다.

긴글 읽어주셔서 감사합니다.

추)
본문을 보시고, 코드 실행이 안되신다는 분들이 있습니다.
아마도 프레임워크 추가와 헤더 import에 대한 언급이 없어서 그런거라 판단됩니다. 그래서 간단한 이미지를 몇가지 첨부하겠습니다.
1. 프로젝트에 QuartzCore.framework 추가

2. 소스코드 추가 부분에 ‘QuartzCore/QuartzCore.h’ 임포트

3. 구현 부분

XCode4에서 정적라이브러리 사용

프로그래밍을 하다보면 재사용성에 대한 고민을 안 할수가 없다. 이런 고민은 스마트폰 앱에서도 마찬가지이다.
코드의 통일성, 활용도를 높이기 위한 재사용성을 하기 위해서 여러방법이 있지만, XCode에서는 정적라이브러리를 만드는 것이 가장 손쉬운 방법이다. 하지만, 이런 손쉬운 방법조차도 처음 해보는 경우에는 각 설정이 어디에 있는지 손에 익지 않아 시간을 많이 사용하는 것이 사실이다.
이번 포스트에서는 만들어진 정적라이브러리를 사용하기 위해서 설정해야 하는 곳을 간단하게 설명할 예정이다.

우선, 자신이 만든 간단한 정적라이브러리를 만든다. 만든 정적라이브러리의 바이러리파일과 헤더파일을 준비한다. (바이러리파일 : xxx.a , 헤더파일 : xxx.h)
1. 정적라이브러리 바이러리파일을 Frameworks에 포함시킨다.
2. 헤더의 경로를 잡아준다.
: TARGET->Build Setting->Header Search Paths : xxx.h의 경로(파일명 미포함)
3. 원하는 소스에서 #import “xxx.h” 후 원하는 메소드 사용.

간단하게 텍스트 위주로 설명했다. 별로 어렵지 않은 것은 바이러리 파일은 링크와 관련된 것이고, 헤더 파일은 컴파일과 관련된 것이라는 사실. 사실 딱 두가지 작업만 잘 맞추면 정적라이브러리를 사용하는 것은 어렵지 않다.

포스트를 업데이트할 때 이미지를 삽입해서 좀 더 완전한 포스트를 만들겠습니다.

카테고리:iPhone-iPad 태그:,
%d 블로거가 이것을 좋아합니다: