UIButton 의 터치 영역을 확장하는건 생각보다 자주 필요한 기능입니다.


예를 들면 디자이너가 10x10 크기의 이미지를 주고 버튼을 만들기 위한 가이드를 주면,

버튼을 만들고 좌표를 잡고 10x10 크기의 이미지를 넣게 되면 터치 영역이 10x10 밖에 안되서 사용이 거의 불가합니다.


디자이너가 투명영역 크기까지 잡아서 30x30 사이즈 안에 10x10 이미지를 넣어서 주면, 

터치 영역이 30x30이 될텐데 거기까지 고려해주는 디자이너는 찾기 어렵... 또는 개발자가 알아서 잘 해줘요 라고 하기도 하죠.


암튼 그래서 필요한 기능.


보통 개발 할 때 당연히 구글에 검색을 하면 이런 저런 방법이 많이 나오는데

제가 선택한 방법은 터치 영역을 확대 해버리는 방식입니다.


http://stackoverflow.com/questions/808503/uibutton-making-the-hit-area-larger-than-the-default-hit-area



여기 보면 중간에 - (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event 를 활용하는 겁니다.

실제 자기 자신의 크기에 마진 크기를 추가해서 터치 영역을 반환하기 때문에 더 큰 터치 영역 확장이 됩니다.



간단히 정리해보면 아래와 같은 Custom Class 를 만들어서 Storyboard 에서 지정해주기만 하면 됩니다.



ExpandTouchButton.h

#import <UIKit/UIKit.h>


@interface ExpandTouchButton : UIButton


@end



ExpandTouchButton.m

#import "ExpandTouchButton.h"


@implementation ExpandTouchButton


- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

{

    CGFloat margin = 15.0;

    CGRect area = CGRectInset(self.bounds, -margin, -margin);

    return CGRectContainsPoint(area, point);

}


@end


끝.


iOS 개발하다가 액션시트하나를 쓰려면 UIAlertDelegate를 사용해서 delegating 을 해야 한다

근데 개인적으로 delegate 구조를 안좋아해서. (써야하는 곳이 있기는 하다.)

block으로 처리되는게 없나 싶어서 찾아봤더니 당연히(?) 있었다.


4년전에 이미 만들어진 라이브러리 -_-)ㅋ


https://github.com/jivadevoe/UIAlertView-Blocks



혹시나 해서 공유합니다.

역시나 MIT License 입니다.

'iOS > 라이브러리' 카테고리의 다른 글

FaceAware  (0) 2016.11.16

https://developer.apple.com/app-store/review/guidelines/kr/#hardware-compatibility


지금까지 한글 버전이 없었던거 같은데 한글 버전이 나왔습니다.


개발자라 (개인 개발로 iOS앱을 내본적은 없고, 안드로이드만 내봤음) 잘 모르고 있었는데

시간 날 때 정독 해봐야겠습니다.


참고하세요 :)

외부에서 이미지를 받아서 화면에 보여줄때

얼굴이 있을 경우 해당 얼굴을 센터에 보여주고 싶을때가 있다.


앨범 자켓을 가져와서 중앙 정렬 했는데 얼굴 위쪽이 잘려서 아래만 남는다 던가 하는 경우.


이때 사용하기 좋은 라이브러리





https://github.com/BeauNouvelle/FaceAware



라이센스는 MIT니까 마음것 사용하고 이거 사용했다고 꼭 써놓읍시다 ㅎ

'iOS > 라이브러리' 카테고리의 다른 글

SIAlertView - block 구조의 액션시트 (Objective-C)  (0) 2016.11.21

# 왜 찾아봤나

iOS7 에서 iOS8 을 넘어가는 시점에 바뀐게 참 많다.

그래서 개발할때 분기 처리해서 개발해야하는 것들이 점점 많아졌고,

(특히 미디어 관련해서)


이미 deprecated 된 메소드를 이용해 개발을 하면 언젠가 문제가 될테니

분기해서 2개 기능을 모두 구현하고는 했는데 도저히 이제는 버릴 코드를 만드는게 시간이 부족해서 안되겠음.



iOS7을 버리려면 근거가 있어야하는데 그게 바로 iOS 버전별 점유율 차트.

어디인가는 있을텐데 매번 찾기 귀찮으니 한번 정리해봤음



# 찾았다

https://developer.apple.com/support/app-store/


애플 개발자 페이지에 간략하게 표기되어있으나 이걸로는 부족!




http://hwstats.unity3d.com/mobile/os-ios.html


유니티를 사용한 기기 버전인거 같음. 게이머들 대상으로 보면될거 같음. 최신기기 비율이 더 높음



https://david-smith.org/iosversionstats/


보고서 형식. 일단은 여기가 최고다.

iOS 7.x이하는 3.9%로 보인다. 생각보다 많네 -_-; 실제 사용비율은 모르겠지만.;

오래된 기기는 최신 앱을 설치하지도 않을거 같지만 일단은 그렇다.



# 결론


어쨌든 결론을 정해놓고 근거를 찾은거라

3.9%가 난 적다고 주장하겠음-_-); 



아마 앱 스토어 개발자 페이지 통계에 가면 실제 내가 개발한 앱의 통계를 볼 수 있을테니 그걸 참고하는게 제일 좋긴 합니다.

(또는 Flurry 라던가 구글 애널리스틱스 라던가를 달아놓으면 더 쉽게 해결)




1. 문제


 원래는 http://until-develop.tistory.com/1 에서처럼 무음 모드인데 스피커로 소리가 나는걸 해결하고 싶었는데,

반대로 무음 모드인데 스피커로 소리를 나게 하는 방법을 찾아보면 문제를 해결 할 수 있을 것 같았다.


 그리고 재생 프로그램인데 사용자의도 - 재생 - 이 명백할때는 뮤트 상태에서도 소리가 나도 괜찮지 않을까? 라는 생각을 했다.



2. 해결


    NSError *setCategoryErr;

    NSError *overrideErr;

    NSError *activationErr;


    

    BOOL setCategoryResult = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryErr];

    BOOL setOverrideResult = [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&overrideErr];

    BOOL setActiveResult = [[AVAudioSession sharedInstance] setActive:YES error:&activationErr];



이렇게 해주면 된다.

그리고 끄려면 AVAudioSessionPortOverrideNone 를 세팅해주면 된다.

 



끝.

1. 문제

무음모드에 둔 상태이고


[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

로 세팅하고 음악 재생 중에 홈 버튼을 눌러서 홈 화면으로 이동하면


백그라운드 상태로 진입하면서 재생은 계속 되는데 스피커로 소리가 나온다.

무음 모드인지를 체크해야하는데 구글링해서 나온 방법은 모두 동작 안하고 있음.


2. 임시 수정

일단 이어폰있는지는 체크가 되서 이어폰 있으면 백그라운드 재생하고, 아니면 막아 둠.



3. 수정 

 로직은 다음과 같음.

 

 이어폰이 꽂혀 있다 -> 뮤트 상태 상관없이 계속 재생

 이어폰이 없다 -> 뮤트 아니면 계속 재생

                      -> 뮤트 상태면 스톱 시킨다.


 백그라운드에서 복귀하면 mute 모드를 따르므로 다시 resume 처리


 3.1) 이어폰 체크 로직

 - (BOOL)isHeadsetPluggedIn

{

    AVAudioSessionRouteDescription *route = [[AVAudioSession sharedInstance] currentRoute];


    BOOL headphonesLocated = NO;

    for (AVAudioSessionPortDescription *portDescription in route.outputs) {

        headphonesLocated |= ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]);

    }

    return headphonesLocated;

}


3.2) 뮤트 체크 로직

 

 https://github.com/hoishing/MuteChecker

 https://github.com/fopina/MuteDetector

 

 위 2개 중에 아래를 사용. 테스트 했을 때는 잘 되는거 같다.

 원리는 위 링크에 설명되어있음.

 

 무음을 재생해서 반응 속도로 하는거 같은데. 가끔 오류 나는거 같긴 한데; 일단 무시




위 로직 적용해서 구현 완료



- 해결 !

+ Recent posts