최근 기존에 iPhone만 지원하던 어플의 iPad 지원을 추가했습니다.
그냥 screen.bound
를 window.bound
로 바꾸면 된다고 생각했었는데, 생각보다 고려해야하는 것이 많아 짧게 언급해보고자 합니다.
시리즈로 하나씩 다뤄보겠습니다. 생각보다 쓸 얘기가 많네요.
iPhone에서 UIAlertController를 사용할 때는 따로 위치를 지정하지 않더라도 AlertView의 경우 화면의 가운데, ActionSheet의 경우 화면의 하단에 위치하곤 합니다.
하지만 기존의 iPhone만 지원할 때의 코드를 그대로 iPad에 빌드하면
...
You must provide location information for this popover through the alert controller's popoverPresentationController.
...
위와 같은 오류를 마주할 수 있습니다. 대충 찾아보면 popoverPresentationController
를 통해 alertController의 위치를 지정해주어라~ 하는 의미인데, https://developer.apple.com/documentation/uikit/windows_and_screens/displaying_transient_content_in_a_popover
오른쪽 사진처럼 iPad의 화면이 넓기 때문에 자유롭게 AlertView의 위치를 지정할 수 있도록 하는 배려인 것 같습니다.
지정하지 않으면 가운데를 default로 주면 안되나
대응은 간단합니다. view
의 midX와 midY를 통해 가운데에 위치하도록 하면 됩니다.
popoverPresentationController.permittedArrowDirections
의 경우는 화살표의 방향인데,
같은 코드를 objective-C로 작성하는 경우 빈 배열을 넘겨줄 수 없습니다.(방법을 아신다면 댓글 부탁드립니다🥲)
if UIDevice.current.userInterfaceIdiom == .pad {
if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
}
위의 함수를 모든 UIAlertController
에 적용하기는 번거롭고, UIAlertController
를 상속하고 init에서 위 함수를 실행하는 EnsuredUIAlertController
class를 생성하고자 했는데, 이게 웬걸? UIAlertController
는 subclassing을 지원하지 않는다고 하네요. 일단 안된다 하니 Extension을 선언하여 UIAlertController(...).ensureAlert()
를 통해 iPad에서의 실행도 보장되도록 처리를 했는데, 이걸 왜 subclassing을 못하게 하는지 저는 참 궁금하네요. 이유를 아신다면 알려주시면 정말 감사하겠습니다!!