iOS 8에서 방향 변경을 처리하는 "올바른"방법은 무엇입니까?
누군가 iOS 8에서 세로 및 가로 인터페이스 방향으로 작업하는 데 "올바른"또는 "가장 좋은"접근 방식을 알려주시겠습니까? 그 목적으로 사용하려는 모든 기능이 iOS 8에서 더 이상 사용되지 않는 것 같습니다. 그리고 내 연구에 따르면 명확하고 우아한 대안이 없습니다. 가로 모드인지 세로 모드인지 스스로 결정하기 위해 너비와 높이를 확인해야합니까?
예를 들어, 뷰 컨트롤러에서 다음 의사 코드를 어떻게 구현해야합니까?
if we are rotating from portrait to landscape then
do portrait things
else if we are rotating from landscape to portrait then
do landscape things
Apple은 UI가 레이아웃과 모양을 크게 변경할 수 있도록 크기 클래스를 사용 가능한 화면 공간의 대략적인 척도로 사용할 것을 권장합니다. 세로 모드의 iPad는 가로 모드 (일반 너비, 일반 높이)와 동일한 크기 등급을 가지고 있다고 가정합니다. 이는 UI가 두 방향간에 다소 유사해야 함을 의미합니다.
그러나 iPad에서 세로에서 가로로의 변경은 크기 클래스가 변경되지 않았더라도 UI를 약간 조정해야 할만큼 충분히 중요합니다. 의 인터페이스 방향 관련 메서드 UIViewController
가 더 이상 사용되지 않으므로 Apple은 이제 다음과 같은 새로운 메서드를 UIViewController
대체로 구현할 것을 권장합니다 .
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
// Code here will execute before the rotation begins.
// Equivalent to placing it in the deprecated method -[willRotateToInterfaceOrientation:duration:]
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Place code here to perform animations during the rotation.
// You can pass nil or leave this block empty if not necessary.
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Code here will execute after the rotation has finished.
// Equivalent to placing it in the deprecated method -[didRotateFromInterfaceOrientation:]
}];
}
큰! 이제 순환이 시작되기 직전과 완료된 후에 콜백을받습니다. 그러나 회전이 세로인지 가로인지 실제로 아는 것은 어떨까요?
Apple은 회전을 단순히 상위 뷰의 크기 변경으로 생각할 것을 권장합니다. 즉, 세로에서 가로로 아이 패드 회전하는 동안, 당신은 루트 레벨보기는 단순히 변화로 생각할 수 bounds.size
에서 {768, 1024}
까지 {1024, 768}
. 이를 알면 위 size
의 viewWillTransitionToSize:withTransitionCoordinator:
메서드에 전달 된를 사용하여 세로 또는 가로로 회전하는지 파악 해야합니다 .
레거시 코드를 새로운 iOS 8 방식으로 마이그레이션하는보다 원활한 방법을 원한다면 UIView 에서이 간단한 범주 를 사용하는 것이 좋습니다. 이 범주 를 사용하여 뷰가 "세로"인지 또는 "가로"인지 여부를 결정하는 데 사용할 수 있습니다. 크기.
요약하자면:
- 크기 클래스를 사용하여 근본적으로 다른 UI를 표시 할시기를 결정해야합니다 (예 : "iPhone과 유사한"UI 대 "iPad와 유사한"UI).
- iPad가 회전 할 때와 같이 크기 클래스 가 변경 되지 않고 컨테이너 (상위보기) 크기가 변경 될 때 UI를 더 작게 조정해야하는 경우
viewWillTransitionToSize:withTransitionCoordinator:
UIViewController 에서 콜백을 사용하십시오 . - 앱의 모든 뷰는 레이아웃에 주어진 공간에 따라 레이아웃을 결정해야합니다. 뷰의 자연스러운 계층 구조가이 정보를 계단식으로 배열하도록합니다.
- 마찬가지로
statusBarOrientation
기본적으로 장치 수준 속성 인를 사용하여 "세로"와 "가로"보기를 레이아웃할지 여부를 결정 하지 마십시오 . 상태 표시 줄 방향은UIWindow
실제로 앱의 가장 루트 수준에있는 것과 같은 것을 처리하는 코드에서만 사용해야 합니다.
smileyborg의 매우 상세한 (및 수용된) 답변을 기반으로하여 다음은 신속한 3을 사용한 적응입니다.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil, completion: {
_ in
self.collectionView.collectionViewLayout.invalidateLayout()
})
}
그리고 UICollectionViewDelegateFlowLayout
구현에서
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// retrieve the updated bounds
let itemWidth = collectionView.bounds.width
let itemHeight = collectionView.bounds.height
// do whatever you need to do to adapt to the new size
}
알림 센터를 사용합니다.
방향 변수 추가 (마지막에 설명)
//Above viewdidload
var orientations:UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
보기가 나타날 때 알림 추가
override func viewDidAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil)
}
보기가 사라질 때 알림 제거
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIDeviceOrientationDidChangeNotification, object: nil)
}
Gets current orientation when notification is triggered
func orientationChanged (notification: NSNotification) {
adjustViewsForOrientation(UIApplication.sharedApplication().statusBarOrientation)
}
Checks orientation (portrait/landscape) and handles events
func adjustViewsForOrientation(orientation: UIInterfaceOrientation) {
if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown)
{
if(orientation != orientations) {
println("Portrait")
//Do Rotation stuff here
orientations = orientation
}
}
else if (orientation == UIInterfaceOrientation.LandscapeLeft || orientation == UIInterfaceOrientation.LandscapeRight)
{
if(orientation != orientations) {
println("Landscape")
//Do Rotation stuff here
orientations = orientation
}
}
}
The reason I add an orientation variable is because when testing on a physical device the orientation notification gets called at every minor move in the device, and not just when it rotates. Adding the var and if statements only calls the code if it switched to the opposite orientation.
From a UI perspective, I believe that using Size Classes are Apple's recommended approach for handling interfaces in different orientations, sizes and scales.
See the section: Traits Describe the Size Class and Scale of an Interface here: https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
"iOS 8 adds new features that make dealing with screen size and orientation much more versatile."
This one is a good article as well: https://carpeaqua.com/thinking-in-terms-of-ios-8-size-classes/
EDIT Updated Link: https://carpeaqua.com/2014/06/14/thinking-in-terms-of-ios-8-size-classes/ (Credit: Koen)
'programing tip' 카테고리의 다른 글
참조되는 글꼴과 PDF 문서에 포함 된 글꼴을 찾는 방법 (0) | 2020.08.20 |
---|---|
문자열 소스의 Python XML ElementTree? (0) | 2020.08.20 |
JS는 임의의 부울을 생성합니다. (0) | 2020.08.20 |
사용자 정의 어댑터를 만들 때 getView () 메서드는 어떻게 작동합니까? (0) | 2020.08.19 |
변수가 배열인지 감지하는 방법 (0) | 2020.08.19 |