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 이전/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에 공백을 줄 수 있다.

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


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UIImageView 이벤트 처리

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

UIImageView에 touch 이벤트를 등록하려면


" userInteractionEnabled " 이라는 property를 YES로 해주어야 한다.

대부분의 view들이 저 값이 default로 YES로 설정되어 있지만,  UIImageView는 무슨 이유에선지

default로 NO가 설정되어 있다.


따라서 UIImageView에 touch이벤트를 등록하고 싶다면 위 property를 변경해주어야 할것이다.



본인도 이거 하나때문에 온갖 뻘짓을 한기억이 있다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] 전화 번호 -(대쉬) 규칙 적용 함수

hagulu 하구루2017. 2. 25. 15:59


voip 앱을 만들다가 필요에 의해서 직접 아이폰 전화 어플에 전화 번호 하나하나 넣는 노가다를 통해서 확인하여 기본적인 국내 통화의 대쉬 규칙을 리스팅하여 함수로 만들었다.


규칙은 아래와 같다


  • 1로 시작하는 세자리까지 대쉬 없음
  • 2로 시작하는 번호는 1-3-4 1-4-4
  • 0으로 시작하는 번호
    • 02로 시작하는 번호 2-3-4, 2-4-4
    • 013로 시작하는 번호 4-3-4, 4-4-4
    • 015로 시작하는 번호 5-4
    • 010, 011, 012, 016, 017, 018, 019로 시작하는 번호 3-3-4, 3-4-4
    • 그외에 0으로 시작하는 번호 3-3-4
  • 0또는 2외에 시작하지 않는 경우
    • 15, 16, 17, 18, 19로 시작하는 경우 4-4
      • 15를 제외한 나머지는 8자리 이상일떄 2-3-4- 2-4-4
    • 그외의 경우 2-3-4 2-4-4


소스는 아래와 같고 사용법은

+ (NSString *) makePhoneNumber:(NSString*) phoneNumStr;


요 메소드에 대쉬가 없는 전화 번호를 NSString 형태로 넣어주면 대쉬가 붙어서 NSString으로 return 해준다.

Global이라는 class 안에서 구현되었다.


// 뒷부분이 3-4 인경우 스트링 만들어줌

+ (NSString *) make34:(NSString *)phoneNumStr withHeadCodeCnt:(NSInteger) headCodeCnt  {
 
    if([phoneNumStr  length] > headCodeCnt && [phoneNumStr  length] <= headCodeCnt + 3) {
 
        return [NSString stringWithFormat:@"%@-%@", [phoneNumStr substringToIndex:headCodeCnt], [phoneNumStr substringFromIndex:headCodeCnt]];
 
    } else if ([phoneNumStr length] > headCodeCnt + 3 && [phoneNumStr  length] < headCodeCnt + 8) {
 
        return [NSString stringWithFormat:@"%@-%@-%@", [phoneNumStr substringToIndex:headCodeCnt], 

                [phoneNumStr substringWithRange:NSMakeRange(headCodeCnt, 3)], [phoneNumStr substringFromIndex:headCodeCnt + 3]];
 
    } else {
 
        return phoneNumStr;
 
    }
 
}
 



// 뒷부분이 3-4 4-4 인경우 스트링 만들어줌
 
+ (NSString *) make34_44 :(NSString *)phoneNumStr withHeadCodeCnt:(NSInteger) headCodeCnt{
 
    if([phoneNumStr  length] > headCodeCnt && [phoneNumStr  length] < headCodeCnt + 8) {
 
        return [self make34:phoneNumStr withHeadCodeCnt:headCodeCnt];
 
    } else if ([phoneNumStr  length] == headCodeCnt + 8) { 

        return [NSString stringWithFormat:@"%@-%@-%@", [phoneNumStr substringToIndex:headCodeCnt], 

                [phoneNumStr substringWithRange:NSMakeRange(headCodeCnt, 4)], [phoneNumStr substringFromIndex:headCodeCnt + 4]];
 
    } else {
 
        return phoneNumStr;
 
    }
 
}
 

// 두개로 
 
+ (NSString *) makeHalf:(NSString *)phoneNumStr withHeadCodeCnt:(NSInteger) headCodeCnt {
 
    
 
    if([phoneNumStr length] > headCodeCnt && [phoneNumStr length] <= headCodeCnt + 4) {
 
        return [NSString stringWithFormat:@"%@-%@", [phoneNumStr substringToIndex:headCodeCnt], [phoneNumStr substringFromIndex:headCodeCnt]];
 
    } else {
 
        return phoneNumStr;
 
    }
 
}
 
+ (NSString *) makePhoneNumber :(NSString *)phoneNumStr {
    
    NSArray* specialCode334_344 = [[[NSArray alloc] initWithObjects:@"010", @"011", @"012", @"016", @"017", @"018", @"019", 
                          @"070",nil] autorelease];
    
    NSArray* specialCode44 = [[[NSArray alloc] initWithObjects:@"15", @"16", @"17", @"18", @"19", nil] autorelease];
    
    if([phoneNumStr hasPrefix:@"1"] && [phoneNumStr length] <= 3) {
        return phoneNumStr;
    } else if([phoneNumStr hasPrefix:@"2"]) {
        return [Global make34_44:phoneNumStr withHeadCodeCnt:1];
    } else if([phoneNumStr hasPrefix:@"0"]) { // 0으로 시작되는 번호
        if([phoneNumStr length] > 2 && [phoneNumStr hasPrefix:@"02"]) {   // 02로 시작되는 번호 2-3-4 2-4-4 규칙
            return [Global make34_44:phoneNumStr withHeadCodeCnt:2];
        } else if([phoneNumStr length] > 3){ // 판별 코드가 3자리
            if([phoneNumStr hasPrefix:@"014"]) { // 014경우 아애 안한다
                return phoneNumStr;
            } else if([phoneNumStr hasPrefix:@"013"]) { // 013경우 4-3-4 4-4-4
                return [Global make34_44:phoneNumStr withHeadCodeCnt:4];
            } else if([phoneNumStr hasPrefix:@"015"]) { // 015경우 5-4
                return [Global makeHalf:phoneNumStr withHeadCodeCnt:5];
            } else if([specialCode334_344 indexOfObject:[phoneNumStr substringToIndex:3]] != NSNotFound) { // 3-3-4 3-4-4 규칙
                return [Global make34_44:phoneNumStr withHeadCodeCnt:3];
            } else {
                return [Global make34:phoneNumStr withHeadCodeCnt:3];
            }
        } else {
            return phoneNumStr;  
        }
    } else { // 그외의 숫자로 시작할경우 
        if([phoneNumStr length] > 2) {
            if([specialCode44 indexOfObject:[phoneNumStr substringToIndex:2]] != NSNotFound) { // 4-4 규칙 
                if(![phoneNumStr hasPrefix:@"15"] && [phoneNumStr length] > 8) { // 15 로 시작하는경우가 아니면  8자리 이상 다시 처리
                    return [Global make34_44:phoneNumStr withHeadCodeCnt:2];
                } else {
                    return [Global makeHalf:phoneNumStr withHeadCodeCnt:4];
                }
            } else { // 두개로 나눠지는 경우가 아닌 경우 대부분
                return [Global make34_44:phoneNumStr withHeadCodeCnt:2];
            }
        } else {
            return phoneNumStr;
        }
        
    }
}


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UITableViewCell 이벤트관리 메소드

hagulu 하구루2017. 2. 25. 15:59

UITableView를 사용하다보면 각 셀에 이벤트를 cell단위로 관리하고 싶을 것이다.


이를 위함 메소드들이 UITableViewCell에 있다.


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

[super setEditing:editing animated:animated];

if(selected) {
 // 선택 되었을때
} else {
// 선택 되지 않앗을때
}
}

해당셀의 선택 여부에 따라 호출되는 메소드로 selected 를 통해서 선택 되었을때와 안 되었을때를 구분하여 cell을 관리 할수 있다.

참고로 selected는 tap이 모두 이루어 진게 되는 상태를 말한다.
따라서 Highlight  를 처리하는 메소드가 따로 있다.

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated

사용법은 위와 같다.

그리고 테이블 삭제를 할때 오른쪽에 삭제 버튼이 생기는 edit 상태일떄를 처리하는 메소드도 제공한다


- (void)setEditing:(BOOL)editing animated:(BOOL)animated

이 세개의 메소드는 보는것처럼 쉽게 이용할수 있다.


그외에 tableView에서 여러 셀을 동시에 편집하는 화면에서 왼쪽 (-) 처럼 생긴 것을 터치했을때 오른쪽에 삭제 버튼이 나타나는 상황을 캐취하는 메소드 또한 있다.

무슨말일까.. 저위에말.. ㅋㅋ


- (void)didTransitionToState:(UITableViewCellStateMask)state {

    [superdidTransitionToState:state];

    

    if(state & UITableViewCellStateShowingDeleteConfirmationMask) {

  // 삭제버튼이 나타 낫을때

    } else {

 // 삭제버튼이 없을때

    }

}


셀의 변화가 일어 낫을때 불리는 메소드로 의심이 되는데 굳이 상세히짚고 넘어갈 마음은 없다.

if(state & UITableViewCellStateShowingDeleteConfirmationMask)  이부분이 어떤 원리로 작동하는 지는 모르겠다.. 구글링과 나의 껴 마추기로 찾은 조합이니 다른데서 오작동을 할가능성은 다분하다. 


이정도만 활용해도 tableView의 셀의 이벤트에 대응할수 있을것이다.



댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] superview 혹은 superview 의 ViewController object 얻어 오기

hagulu 하구루2017. 2. 25. 15:58

UIView를 따로 빼서 사용하다 보면 superview에 접근해야 하는 일이 자주 발생한다 .


이때 간단히

self.superview
를 통해서 object를 얻어와 작업을 할수 있다.

또한, superview의 ViewController에 접근하고 싶다면

[self.superviewnextResponder]

를 통해서 쉽게 object를 얻어 올수 있다.

이때 superview는 viewController의 view 이어야 한다.


제대로 참조되지 않는다면 nextResponder에대해서 알아보고, 다른 방법을 찾아 봐야 할것이다.


댓글

댓글쓰기 폼