본문 바로가기

분노=프로그래밍/iOS

ios 회전 시 뷰의 리사이즈 문제

지난 8월 ios 라이브러리 유지보수중 겪은 문제이다.

 

제공하는 라이브러리는 적용하는 개발자에게 뷰를 제공하며

 

뷰를 터치하면 새로운 뷰 컨트롤러와 그 안에 존재하는 웹뷰를 띄우게 된다.(하단 그림 참조)

 

 

유지보수했던 앱 구조

 

고객사의 요청으로 회전에 따른 뷰를 구현하고 있었는데

다음과 같은 문제가 발생했다.

 

VerticalOrientation(정상)

 

 

HorizonOrientation(비정상:하단 흰색부분이공백임)

 

SDK 내부 구조는 UIViewController.view 에 mainView 라는 웹뷰를 가지고 있음.

스크린샷 및 시뮬레이팅 결과 좌표가 깨진다고 추측되어 다음과 같이 수정.

 

기존

-(void)resizeView{

self.view.frame = CGRectMake(....

mainView.frame = CGRectMake(...

...

}

 

변경 후

-(void)resizeView{

self.view.frame = CGRectMake(....

mainView.frame = self.view.bounds(...

...

}

 


 

수정 후 iOS 5.x simulator에선 정상 동작

 

그러나 ios 4.x simulator에선 orientation(vertical, horizon)에 따른 사이즈가

반대로 적용되어 동작함을 확인

(가로에선 세로사이즈, 세로에선 가로사이즈로 뷰가 깨짐)

 

UI를 그리는 Thread가 하나라고 가정하고, 회전 이벤트와 관련된 lifeCycle에서

회전 이벤트의 적용과 resizing이 겹친다고 추측되어 다음과 같이 수정

 

기존 : shouldAutorotateToInterfaceOrientation에서 직접 사이즈를 변경 요청

-(void)shouldAutorotateToInterfaceOrientation:...{

     [self resizeLandingPage:toInterfaceOrientation];

     return YES;

}

 

변경 후 : shouldAutorotateToInterfaceOrientation는 회전에 따른 리턴만 적용하고

           사이즈 변경은 willAnimateRotationToInterfaceOrientation에서 구현

-(BOOL)shouldAutorotateToInterfaceOrientation:...{

     return YES;

}

 

//추가 override method 구현

//rotateAnimation이 발생하기 직전에 수행되는 rotate LifeCycle 관련 메소드

-(void)willAnimateRotationToInterfaceOrientation:...{

     [self resizeView:toInterfaceOrientation]l;

}

 

ios 4.2, 4.3, 5.0, 5.1 simulator 및 iPhone 3GS(5.0.1), iPad2(5.1.1) 정상 동작 확인 완료

 

 

 

 

 

오후 추가 작업

아이패드 해상도 추가 적용을 위해 resizeView 메소드에서 frameSize 참조 변수 수정

기존

   if(orientation == 수직일 때)

         deviceWidth = CGRectMake(0,0,320,480);

   else

         deviceWidth = CGRectMake(0,0,480,320);

   CGRect frameWidth = deviceWidth; //

   ....

 

 

변경

   CGRect frameSize = self.view.bounds;

   CGFloat frameWidth = frameSize.size.width;

   ...

   위와 같이 self.view.bounds를 참조하도록 변경

 

기타 사항


self.view.frame의 경우 시뮬레이터에서 orientation에 따른 사이즈가 반대로 찍혔으나,

bounds의 경우 정상적인 사이즈가 로그에 찍혀서 bounds를 사용했다.

bounds를 사용할 경우 현재 디바이스의 Orientation를 기준으로 width, height값이 적용된

값을 리턴한다. 자세한 건 좀 더 검색해서 정리하도록 하겠다.

 

 


 

*느낀 점

그렇다. 자료 조사로 더 확실히 알아야겠지만, UI기반으로 동작하는 Android나 iOS가

단일 쓰레드로 UI를 갱신한다는 점을 소중히 여기지 않은 나의 잘못이다.

마구 잡이로 될 때까지 디버깅하지 말고, 가설과 실험을 통해 차근차근 해결해 나가자.

그리고... 공부좀 하자. =_=;

'분노=프로그래밍 > iOS' 카테고리의 다른 글

duplicate symbols for architecture i386  (0) 2012.12.07