2011년 4월 7일 목요일

[iOS] UIView's bounds on UINavigationControl

콩글리쉬 영어 제목을 한글로 풀어써보자면 (-_-) UINavigationController에 특정 뷰를 뷰 영역에 집어 넣었을 때 이 뷰의 위치 및 크기에 관한 이야기다.

사실 위치에 관해서는 이야기 할 게 없다. origin.x, origin.y를 0, 0으로 맞춰주면 알아서 네비게이션 바 아래에 착 달라붙는다.

하지만 크기는 다르다. 네비게이션 콘트롤러의 지배하에 놓이는 뷰의 높이는 어처구니 없게도 인디케이터(아이폰 화면 제일 위에 안테나나 시간, 배터리양 등이 표시되는 막대기. S모사에서 사용하는 용어인데 아이폰에서의 공식 명칭은 모르겠다)의 크기만 뺀 값이었다. 즉, 아이폰 3G/3GS에서 일반적인 네비게이션 컨트폴러에 루트뷰 컨트롤러 및 뷰를 올려놓으면 이 뷰의 크기는 360, 460 (세로 기준) 으로 잡힌다. (즉 인디케이터는 20.0의 높이라는 것). sizeToFit 같은 메소드를 던져봐도 이렇게 잡힐 뿐이다.

왜 그러지 이유는 잘 모르겠다.

만약 이 뷰에서 그림을 그리는 등 크기에 굉장히 민감한 작업을 해야한다고 가정해보자. 뷰의 높이가 실제 보이는 영역과 차이가 나기 때문에 뷰의 아랫쪽에 그리는 그림은 화면 상에서 보이지 않게 된다. 그렇다면 뷰의 크기를 화면에 보이는 영역 만큼 정확하게 잡아주어야 한다.

그래서 수동으로 네비게이션 바의 높이를 구해서 실제로 뷰를 생성할 때 빼 주도록 하는 식으로 구현해서 해결 했다.

네비게이션 바의 높이는 다음 코드로 구할 수 있다.
[[someNavigationController navigationBar] bounds].size.height;
위 코드가 에러가 날지는 시험 안해 봤... 하여간 UINavigationController의 프로퍼티로 navigationBar 라는게 있는데 이 녀석도 어차피 UIView 에서 상속된 녀석이라 bounds/frame 같은 프로퍼티를 가지고 있다.

아이폰3G/3GS 기준이라면 아마 44.0이 들어올 것이다. 아이폰4의 레티나일 경우 88.0이 돌아올지에 대해서는 모르겠다. ;;

하여간 뷰 생성 시 위 수치를 빼 주면 정확히 크기가 들어맞는다. 귀찮다면 44.0을 높이에서 빼 주기만 해도 될 것이지만 나 같이 크기에 민감한(?) 개발자라면 이런 식으로 값을 구해서 처리하는게 좋을지도 모르겠다.

더 좋은 방법이 있다면 좋겠는데 찾기가 어렵다.. ;;

ps. 언급하진 않았는데, 위 방식대로 뷰의 크기를 잡아주려면 루트 뷰 컨트롤러는 손으로 만들어야 된다. -_-; 귀찮귀찮...

댓글 없음 :