2013 이전/iOS개발

[iPhone 개발] keyboard 애니메이션 정보 얻기

hagulu 하구루2017. 2. 25. 16:06

키보드에 붙어 다니는 뷰를 만들다 보니 keyboard 가 가지고 있는 애니메이션과 동일하게 해당뷰의 애니메이션을 지정해주어야 한다.

예전 iOS4 까지는

[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
위와 같은 애니메이션을 주면 키보드와 혼연일체로 움직인다.

하지만 iOS5 로 업데이트 되면서 keyboard 가 빨라 졌다.

테스트를 통해서 확인해 본결과 duration이 0.26으로 줄어 들었다.

게다가 iOS5에는 일본어 키보드에 힌트를 위한 뷰가 키보드위에 생겨났다.

이에 관한 것은 http://hagulu.com/129 포스트를 참고 하길 바란다.

일본어 키보드 때문에 대응해야하는 애니메이션이 있는데,

기존에 다른 언어 키보드가 있을때 일본어 키보드로 변경될때는  애니메이션이 없이 움직인다.

따라서 키보드 위에 붙어 다니는 뷰에서 애니메이션이 없어야 한다.

일본어 키보드가 뜨면 키보드 위에 붙어있는 뷰가 애니메이션이 적용되어 부자연스럽게 보여진다.

이렇게 iOS4 이전과 iOS5 이후를 if문 없이 대응 할수 있는 방법을 설명하려고 한다.

위에 소개된 포스트에서 이용하던 것과 비슷한 방법이다.

먼저 아래에 두개의 notification을 설정해 준다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

해당 notification은 보시는 봐와 같이 키보드가 나타나거나 사라지려 할때 나타나는 notification 이다.

이때에 notification 이 가지고 있는 정보를 통해서 간단하게 해당 키보드의 애니메이션 정보를 가져올수 있다.

- (void)keyboardWillShow:(NSNotification *)notification {
    NSLog(@"keyboard will show");
   
    NSTimeInterval keyboardAnimationDuration;
    UIViewAnimationCurve keyBroadAnimationNumber;

    NSValue* value = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    [value getValue:&keyboardAnimationDuration];
    
    value = [notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    [value getValue:&keyBroadAnimationNumber];
    
}

- (void)keyboardWillHide:(NSNotification *)notification {
    NSLog(@"keyboard will hide");
   
    NSTimeInterval keyboardAnimationDuration;
    UIViewAnimationCurve keyBroadAnimationNumber;

    NSValue* value = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    [value getValue:&keyboardAnimationDuration];
    
    value = [notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    [value getValue:&keyBroadAnimationNumber];
}
위와 같이 UIKeyboardAnimationDurationUserInfoKey와 UIKeyboardAnimationCurveUserInfoKey를 통해서 애니메이션 시간과 애니메이션 curve 정보를 얻어 올수 있고 이를 통해서 키보드가 나타날때와 사라질때 뷰를 관리해주면 키보드와 혼연일체로 움직이는것을 확인해 볼수 있을것이다.
 


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] mov 파일 mp4로 변환하기

hagulu 하구루2017. 2. 25. 16:06

안드로이드와 호환이 되는 파일 전송을 구현하다 보니 동영상 전송에 문제가 발생했다.

 
일반적으로 아이폰 비디오 레코더를 이용을 하게되면,
mov라를 확장자의 quickTimeMovie라는 방식으로 저장이 되어 진다.
이 파일을 그대로 안드로이드에 전송을 했더니
안드로이드에서는 하드웨어 코덱을 통해서는 재생을 할수가 없었다.
quick time movie 와  mpeg-4는 외부 포멧만 다를뿐 내부의 영상과 음성 코덱은 유사하다.
따라서 빠르게 변환이 가능한 방법이 있지 않을까 하고 찾다가 방법을 찾게 되었다.
바로 iOS 4 부터 지원되는 AssetLibrary를 이용하는 방법이다
이를 통해서 아래와 같이 구현해 보았다.
변환을 원하는 파일의 NSURL 과 저장을 원하는 파일 path의 NSString 을 주면 해당 path에 저장이 되게 된다.
+ (void) convertVideoQtimeToMpeg4:(NSURL *) videoURL withPath:(NSString *)videoPath {
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
    
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];

    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
        
        exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
        
        exportSession.outputFileType = AVFileTypeMPEG4;
        
        CMTime start = CMTimeMakeWithSeconds(0.0, 600);
        
        CMTimeRange range = CMTimeRangeMake(start, [avAsset duration]);
        
        exportSession.timeRange = range;
        
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            switch ([exportSession status]) {
                    
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                    break;

               case AVAssetExportSessionStatusCompleted:
                     NSLog(@"Export Success");
                     break;
                    
                case AVAssetExportSessionStatusCancelled:
                    
                    NSLog(@"Export canceled");
                    
                    break;
                    
                default:
                    
                    break;
                    
            }
            
            [exportSession release];
            
        }];
        
    }
}

이 중에서 초기화 부분이 중요한데 presetName 에
아래처럼 AVAssetExportPresetPassthrough 를 지정해 주어야 다른 포멧으로 변환이 가능하다
 
[[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
아래와 같이 AVAssetExportPresetMediumQuality 와 같은 파라미터를 주고 outputFileType를 AVFileTypeMPEG로 주게 되면 SIGNAL ABORT가 발생하고 죽게 된다.
 
 AVAssetExportSession *exportSession  = [[AVAssetExportSession alloc]initWithAsset:avAsset AVAssetExportPresetMediumQuality];

exportSession.outputFileType = AVFileTypeMPEG4;
해당 AVAssetExportSession 의 지원되는 output 포멧을 확인하고 싶을때는 AVAssetExportSession 의 supportedFileTypes propert를 통해서 확인해 볼 수가 있다.


추가로 유의 할 것은 이 방식은 asynchronous 이다.

그렇기 때문에 위와 같이 변환을 한 이후에 바로 이를 이용할수 있는것이 아니다
 [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            switch ([exportSession status]) {
                    
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                    break;

               case AVAssetExportSessionStatusCompleted:
                     NSLog(@"Export Success");
                     break;
                    
                case AVAssetExportSessionStatusCancelled:
                    
                    NSLog(@"Export canceled");
                    
                    break;
                    
                default:
                    
                    break;
                    
            }
            
            [exportSession release];
            
        }];

당황하지 않길 바란다 이 소스는 위에 있는 전체 소스의 일부분이다. 

따라서 위 소스와 같이 exportAsynchronouslyWithCompletionHandler 를 등록하여 "AVAssetExportSessionStatusCompleted"를 확인해야 한다.

이를 꼭 유의해서 사용하기 바란다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UIView 에 간단한 이벤트 적용하기

hagulu 하구루2017. 2. 25. 16:05

Button이 아닌 일반 UIView에 각종 터치 체스췌를 등록하는 방법이다.

iOS sdk4.0부터 지원되는것으로 알고 있다.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapPiece:)];
[piece addGestureRecognizer:tapGesture];
[tapGesture release], tapGesture = nil;
UITapGestureRecognizer 를 만들고 액션을 지정해주면 된다.

그리고 해당 뷰에 addGestureRecognizer 를통해 등록을 해주면 해당 view에 이벤트를 등록해 줄수 있다.


UIPanGestureRecognizer
UILongPressGestureRecognizer

위처럼 Tab이외에도 여러 이벤트가 있고 잘 활용하면 편하게 이벤트를 관리 할수 있을것이다

댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] CGImage의 Orientation

hagulu 하구루2017. 2. 25. 16:05

UIImage 의 CGImage를  Quartz 2D를 통해 그리다 보면 UIImage를 통해서 그릴때와 다르게

Orientation이 제대로 적용이 안되게 될것이다.
섬네일을 만들기 위해서 이미지를 일정 크기로 축소를 하다가 발견한 것인데,
 
UIImage에는 imageOrientation라는  property orientation 정보가 들어 있고, 그 정보를 통해서 CGImage를 회전하여 보여주게된다.
즉, CGImage 자체는 Orientation이 적용되지 않은 순수한 이미지 정보인것이다.
때문에 CGImage를 이용할때 UIImage의 imageOrientation정보를 이용해 변경 해야한다.
imageOrientaion의 데이터 형은 다음과 같다 .
typedef enum {
   UIImageOrientationUp,
   UIImageOrientationDown,   // 180 deg rotation
   UIImageOrientationLeft,   // 90 deg CCW
   UIImageOrientationRight,   // 90 deg CW
   UIImageOrientationUpMirrored,    // as above but image mirrored along
   // other axis. horizontal flip
   UIImageOrientationDownMirrored,  // horizontal flip
   UIImageOrientationLeftMirrored,  // vertical flip
   UIImageOrientationRightMirrored, // vertical flip
} UIImageOrientation;

그리고 다음은 본인이 이용하기위해 UIImage와 줄이려는 이미지 사이즈를 통해 orientation이 적용된 CGImage로 만들어진 순수한 UIImage를 리턴하는 메소드 이다.

-(UIImage*) imageWithOrientationInCGImage:(UIImage* )image withSize:(CGSize)imageNewSize{
    
    UIImageOrientation imageOrientation = image.imageOrientation;
    
    UIImage* resultImage;
    UIGraphicsBeginImageContext(CGSizeMake(imageNewSize.width, imageNewSize.height));
    CGContextRef context = UIGraphicsGetCurrentContext();
    switch (imageOrientation) {
        case  UIImageOrientationUp:
            CGContextTranslateCTM(context, 0, imageNewSize.height);
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.width, imageNewSize.height), image.CGImage);
            break;
        case UIImageOrientationDown:
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.width, imageNewSize.height), image.CGImage);
            break;
        case UIImageOrientationLeft:
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextScaleCTM(context, -1.0, 1.0);
            CGContextTranslateCTM(context, 0, imageNewSize.height);
            CGContextRotateCTM (context, -90 * M_PI / 180);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.height, imageNewSize.width), image.CGImage);
            break;
        case UIImageOrientationRight:
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextScaleCTM(context, -1.0, 1.0);
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextRotateCTM (context, 90 * M_PI / 180);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.height, imageNewSize.width), image.CGImage);
            break;
        default:
            
            break;
    }

    resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return resultImage;
}

UIImage에 있는 imageOrientation을 확인해서 CGImage를 변경하여 새로운 UIImage에 넣어주는 방식이다.

댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] 이미지 일부 늘리기

hagulu 하구루2017. 2. 25. 16:04

iPhone을 탈옥해서 카카오톡이나 기본 문자앱의 말풍선을 바꿔 본사람은 알겠지만,

이미지가 여러개로 쪼개져 있는것이 아니고 하나로만 이루어져 있다.
나도 이와 비슷한 앱을 개발하다 보니 이점이 궁금해 졌다.
검색능력의 부족으로 적당히 찾다가, 이미지를 직접 Quartz 2D로 여러 등분을 내서 노가다로 진행을 했엇다.

하지만 아무리 생각해도 이게 아니라고 생각하다가.. 결국엔 찾았다..

메소드 하나면 되는것을 너무 뻘짓을 햇구나 싶었다.
다른 사람이 나 같은 전차를 밟지 않기를 바라며 태그를 왕창 넣어서 포스팅 하려 한다.
UIImage* chatBubble = [[UIImage imageNamed:@"chat_bubble.png"]  stretchableImageWithLeftCapWidth:16 topCapHeight:16];
UIImageView* chatBubbleImaegView =[[UIImageView alloc] initWithImage:chatBubble];

위와 같이 이미지에 stretchableImageWithLeftCapWidth:topCapHeight: 메소드를 통해서 각각 가로 세로의 늘어나야할 지점의 좌표를 지정해준면, 이 좌표가 지정된 UIImage를 리턴해 준다.

 그리고 UIImage를 UIImageView에 지정하고 UIImageView의 frame을 통해 이미지 크기를 지정하면 자연스럽게 해당이미지가 지정한 좌표를 기준으로 늘어 나게 된다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] 키보드 변경에 따른 View 변환

hagulu 하구루2017. 2. 25. 16:03

iOS5로 업데이트 되면서 일본어 키보드에 보는것 처럼 입력을 보조하기 위한  줄이 생겼다.





예전에는 키보드의 크기가 동일해서 따로 처리하지 않아도 될 부분이었으나,
이번 업데이트로 인해 키보드 크기를 동적으로 대응해야 할 경우가 생기게 되었다.
이를 대응하기 위한 키보드가 변경될때마다 높이를 확인할 수 있는 방법을 소개 하겠다.
일단 키보드가 변경될때 마다 호출되는 notification을 설정해 주어야 한다.
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

보는것처럼 UIKeyboardWillShowNotification 를 등록해 주게 되는데, 이름에서 보는것처럼 키보드가 보일때, 발생하는 notification 이다.

 이는 제일 처음 키보드가 보여질때 뿐 아니라 키보드의 언어가 바뀔때 또한 새로운 키보드가 보여지는 것이기 때문에 키보드가 바뀔때 마다 notification이 발생하게 된다.
 그리고 selector에 설정한 method를 구현하면 되는데, 그 안에서 키보드의 Rect를 구하는 방법은 다음과 같다.
- (void)keyboardWillShow:(NSNotification *)notification {
    NSLog(@"keyboard will show");
    
    CGRect t;
    [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &t];
}
notification의 userInfo 로 부터 UIKeyboardFrameEndUserInfoKey의 값을 가져 오게 된다.

이를 이용하면 간단히 키보드의 위치의 변경에 따라 뷰를 동적으로 관리 할 수 있을것이다.


댓글

댓글쓰기 폼

2013 이전/기타

Syntax highlighter 3.x 자동 줄 바꿈

hagulu 하구루2017. 2. 25. 16:02

블로그에 소스를 공유하다 보니 Syntax highlighter를 설치하여 사용하게 되었다.


그런데 최신 버젼인 3.x 을 설치하였는데, 다른곳에서 쉽게 볼수 있던, 자동 줄바꿈이 되지 않았다.

셋팅이 바꼇는지 확인해보고 googling을 해보았는데,

결론은..

3.x 대에서는 기본적으로 자동 줄바꿈이 되지 않고 가로 스크롤이 생겨 버린다.

issue로 등록되었는지는 확인 되진 않았지만 지금 나온 최신 버젼까지는 지원이 안되는것 으로 확인되었다.


그래서 결국 2.x 으로 설치하여 지금은 사용중이다.

줄바꿈이 꼭 필요하다면 2.x 최신버젼을 사용해 보기 바란다.


단, 3.x 에는 2.x에서 문제 였던 선택할때 line 번호까지 선택되던 문제가 해결되어 있다.

 
따라서 버젼 선택은 사용자의 판단에 맡기겟다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] audio 출력 변경하기

hagulu 하구루2017. 2. 25. 16:02

audio를 이용하는 앱을 만들다 보면 해당 audio를  speaker 로 출력하고 싶을 수 있을 것이다.

그때 이용하는 것이 AudioSession 이다
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);

다음과 같이 해당 property를 바꿔주는 방식으로 speaker로 출력을 변경할 수 있다.


다시 일반 출력으로 바꾸고 싶을때는

kAudioSessionOverrideAudioRoute_Speaker 대신에,


kAudioSessionOverrideAudioRoute_None 로 위와 같은 방식으로 property 를 새로 지정해 주면 된다.

audio player 객체와 관계 없이 어디서든 변경할 수 있다.

당연히 AVFoundation.framework 를 추가해 주어야 하고,


#import <AVFoundation/AVFoundation.h>

#import <AudioToolbox/AudioToolbox.h>

요 두가지가 import되어야 한다.

댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UITableViewCell 위에 UIImageView에 roundCorner 적용

hagulu 하구루2017. 2. 25. 16:01

UITableViewCell 위에 View에 layer를 이용하여 cornerRadius를 적용하게되면


스크롤 속도에 심각한 영향을 끼치게 된다.


포토샵으로 이미지를 만들어서 덮어버리는 꼼수를 이용하려 했으나, 나중을 대비해서 구글링하다가 방법을 찾고 적용해 본결과 스크롤에 영향을 끼치지 않고 해결할 수 있는 방법을 찾았다.

내 소스가 아니라 링크만 걸어 놓겠다.





댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UITableView 상단 공백 만들기

hagulu 하구루2017. 2. 25. 16:01

UITableView를 Customize 하다보면 상단에 공백이 필요한 경우가 있다.


frame에 point의 x 를 내리면 스크롤되는 부분또한 내려가서 UITableView자체에 공백을 주기는 힘들다

이럴때 이용할수 있는 방법이 바로 UITableView에  (UIView*) tableHeaderView라는 property에 공백의 UIView를 넣어 주는것이다.

하단공백에는  (UIView*)  tableFooterView property를 이용하면 되겟다

그렇게 하면 스크롤을 유지하면서 UITableView에 공백을 줄 수 있다.

너무 간단한 방법이므로 예제소스는 생략하겠다.


댓글

댓글쓰기 폼

hagulu.com

.....

VISITED

Today : 2

Total : 179,450

Lately Comment