iOS 8을 사용하여 iPad에서 UIAlert 컨트롤러를 올바르게 표시하기
iOS 8.0에서 Apple은 UIAction을 대체하기 위해 UIAertController를 도입했습니다.Sheet. 안타깝게도, Apple은 그것을 어떻게 제시해야 하는지에 대한 어떤 정보도 추가하지 않았습니다.hayaGeek의 블로그에서 그것에 대한 항목을 찾았지만, iPad에서는 작동하지 않는 것 같습니다.보기가 완전히 잘못되어 있습니다.
잘못됨: 가잘못됨위:
정답:
다음 코드를 사용하여 인터페이스에 표시합니다.
let alert = UIAlertController()
// setting buttons
self.presentModalViewController(alert, animated: true)
아이패드용으로 추가할 수 있는 다른 방법이 있나요?아니면 Apple이 iPad를 잊어버린 것일까요, 아니면 아직 구현되지 않은 것일까요?
다음을 제시할 수 있습니다.UIAlertController
에서 을사하여나타나서쑥불용▁from▁using서▁a를 사용하여.UIPopoverPresentationController
.
Obj-C에서:
UIViewController *self; // code assumes you're in a view controller
UIButton *button; // the button you want to show the popup sheet from
UIAlertController *alertController;
UIAlertAction *destroyAction;
UIAlertAction *otherAction;
alertController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
destroyAction = [UIAlertAction actionWithTitle:@"Remove All Data"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
// do destructive stuff here
}];
otherAction = [UIAlertAction actionWithTitle:@"Blah"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// do something here
}];
// note: you can control the order buttons are shown, unlike UIActionSheet
[alertController addAction:destroyAction];
[alertController addAction:otherAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];
UIPopoverPresentationController *popPresenter = [alertController
popoverPresentationController];
popPresenter.sourceView = button;
popPresenter.sourceRect = button.bounds;
[self presentViewController:alertController animated:YES completion:nil];
Swift 4.2에 대한 편집은 동일한 블로그를 많이 사용할 수 있지만 검색 시간을 절약할 수 있습니다.
if let popoverController = yourAlert.popoverPresentationController {
popoverController.sourceView = self.view //to set the source of your alert
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement.
popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction
}
iPad에서 경고는 새로운 UIPopover Presentation Controller를 사용하여 팝업으로 표시되며, 다음을 사용하여 팝업 프레젠테이션의 앵커 포인트를 지정해야 합니다.
- 막대ButtonItem
- 또는 sourceView 및 sourceRect
앵커 포인트를 지정하려면 UIAertController의 UIPopoverPresentationController에 대한 참조를 가져와 다음과 같이 속성 중 하나를 설정해야 합니다.
alertController.popoverPresentationController.barButtonItem = button;
샘플 코드:
UIAlertAction *actionDelete = nil;
UIAlertAction *actionCancel = nil;
// create action sheet
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:actionTitle message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
// Delete Button
actionDelete = [UIAlertAction
actionWithTitle:NSLocalizedString(@"IDS_LABEL_DELETE", nil)
style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Delete
// [self deleteFileAtCurrentIndexPath];
}];
// Cancel Button
actionCancel = [UIAlertAction
actionWithTitle:NSLocalizedString(@"IDS_LABEL_CANCEL", nil)
style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// cancel
// Cancel code
}];
// Add Cancel action
[alertController addAction:actionCancel];
[alertController addAction:actionDelete];
// show action sheet
alertController.popoverPresentationController.barButtonItem = button;
alertController.popoverPresentationController.sourceView = self.view;
[self presentViewController:alertController animated:YES
completion:nil];
Swift 2에서 iPhone 및 iPad에 올바르게 표시하려면 다음과 같은 작업을 수행해야 합니다.
func confirmAndDelete(sender: AnyObject) {
guard let button = sender as? UIView else {
return
}
let alert = UIAlertController(title: NSLocalizedString("Delete Contact?", comment: ""), message: NSLocalizedString("This action will delete all downloaded audio files.", comment: ""), preferredStyle: .ActionSheet)
alert.modalPresentationStyle = .Popover
let action = UIAlertAction(title: NSLocalizedString("Delete", comment: ""), style: .Destructive) { action in
EarPlaySDK.deleteAllResources()
}
let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel) { action in
}
alert.addAction(cancel)
alert.addAction(action)
if let presenter = alert.popoverPresentationController {
presenter.sourceView = button
presenter.sourceRect = button.bounds
}
presentViewController(alert, animated: true, completion: nil)
}
합니다.-[UIPopoverPresentationController presentationTransitionWillBegin]
다음 메시지가 표시됩니다.
치명적 예외: NSGenericException 응용 프로그램이 UIAertControllerStyleAction 스타일의 UIAertController(<UIAertController: 0x17858a00>)를 표시했습니다.Sheet. 이 스타일을 가진 UIAlert 컨트롤러의 모달 프레젠테이션 스타일은 UIModal Presentation Popover입니다.알림 컨트롤러의 팝업 표시 컨트롤러를 통해 이 팝업에 대한 위치 정보를 제공해야 합니다.sourceView 및 sourceRect 또는 barButtonItem을 제공해야 합니다.경고 컨트롤러를 표시할 때 이 정보를 알 수 없는 경우 UIPopoverPresentationControllerDelegate 메서드 -prepareForPopoverPresentation에서 제공할 수 있습니다.
스위프트 5
iPhone은 "액션시트" 스타일을, iPad는 "경고" 스타일을 사용했습니다. iPad는 화면 중앙에 표시됩니다.sourceView를 지정하거나 뷰를 다른 곳에 고정할 필요가 없습니다.
var alertStyle = UIAlertController.Style.actionSheet
if (UIDevice.current.userInterfaceIdiom == .pad) {
alertStyle = UIAlertController.Style.alert
}
let alertController = UIAlertController(title: "Your title", message: nil, preferredStyle: alertStyle)
편집: ShareToD의 제안에 따라 사용되지 않는 "UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad" 확인란이 업데이트되었습니다.
Swift 3.0 이상 버전에 대한 업데이트
let actionSheetController: UIAlertController = UIAlertController(title: "SomeTitle", message: nil, preferredStyle: .actionSheet)
let editAction: UIAlertAction = UIAlertAction(title: "Edit Details", style: .default) { action -> Void in
print("Edit Details")
}
let deleteAction: UIAlertAction = UIAlertAction(title: "Delete Item", style: .default) { action -> Void in
print("Delete Item")
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in }
actionSheetController.addAction(editAction)
actionSheetController.addAction(deleteAction)
actionSheetController.addAction(cancelAction)
// present(actionSheetController, animated: true, completion: nil) // doesn't work for iPad
actionSheetController.popoverPresentationController?.sourceView = yourSourceViewName // works for both iPhone & iPad
present(actionSheetController, animated: true) {
print("option menu presented")
}
스위프트 4 이상
확장자를 만들었습니다.
extension UIViewController {
public func addActionSheetForiPad(actionSheet: UIAlertController) {
if let popoverPresentationController = actionSheet.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverPresentationController.permittedArrowDirections = []
}
}
}
사용 방법:
let actionSheetVC = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
addActionSheetForiPad(actionSheet: actionSheetVC)
present(actionSheetVC, animated: true, completion: nil)
2018년 업데이트
저는 이러한 이유로 앱을 거부당했고 매우 빠른 해결책은 단순히 조치 시트를 사용하는 것에서 경고로 변경하는 것이었습니다.
매력적으로 작동했고 앱스토어 테스터들을 잘 통과했습니다.
모든 사람에게 적합한 대답은 아닐 수도 있지만 이것이 여러분 중 일부가 빨리 곤경에서 벗어날 수 있도록 도움이 되기를 바랍니다.
Swift 4.2 다음과 같은 조건을 사용할 수 있습니다.
let alert = UIAlertController(title: nil, message: nil, preferredStyle: UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet)
스위프트 5
iPad와 iPhone 모두에서 작동합니다.
수행 시트가 단추 아래로 이동합니다.
iPhone의 경우 작업 시트가 정상적으로 표시되고 iPad가 버튼 아래에 표시됩니다.
actionSheet.popoverPresentationController?.sourceView = fooButton
actionSheet.popoverPresentationController?.sourceRect = fooButton.bounds
화면/보기 중앙에 있는 작업 시트
iPhone의 경우 작업 시트가 정상적으로 표시되고 iPad가 화면/보기 중앙에 표시됩니다.
actionSheet.popoverPresentationController?.sourceView = view
actionSheet.popoverPresentationController?.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
actionSheet.popoverPresentationController?.permittedArrowDirections = []
빠른 해결책은 다음과 같습니다.
NSString *text = self.contentTextView.text;
NSArray *items = @[text];
UIActivityViewController *activity = [[UIActivityViewController alloc]
initWithActivityItems:items
applicationActivities:nil];
activity.excludedActivityTypes = @[UIActivityTypePostToWeibo];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
//activity.popoverPresentationController.sourceView = shareButtonBarItem;
activity.popoverPresentationController.barButtonItem = shareButtonBarItem;
[self presentViewController:activity animated:YES completion:nil];
}
[self presentViewController:activity animated:YES completion:nil];
저는 다음 사항을 추가하기만 하면 되었습니다.
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = navigationItem.rightBarButtonItem
}
작업 시트를 제시하기 전에 다음 코드를 추가하기만 하면 됩니다.
if let popoverController = optionMenu.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
iphone과 ipad 모두에서 작동할 것입니다.
func showImagePicker() {
var alertStyle = UIAlertController.Style.actionSheet
if (UIDevice.current.userInterfaceIdiom == .pad) {
alertStyle = UIAlertController.Style.alert
}
let alert = UIAlertController(title: "", message: "Upload Attachment", preferredStyle: alertStyle)
alert.addAction(UIAlertAction(title: "Choose from gallery", style: .default , handler:{ (UIAlertAction) in
self.pickPhoto(sourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Take Photo", style: .default, handler:{ (UIAlertAction) in
self.pickPhoto(sourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction) in
}))
present(alert, animated: true, completion: nil)
}
코드베이스가 iPhone 및 iPad 장치를 모두 지원하는 경우 다음 사항을 고려합니다.
사용하다present(_ viewControllerToPresent:animated:completion:)
다음과 같은 경우에 정기적으로:
- 프레젠테이션
UIAlertController
와 함께preferredStyle
의.alert
- 프레젠테이션
UIViewController
와 함께.modalPresentationStyle
다음 중:.overFullScreen
.formSheet
.automatic
기본값은 다음과 같습니다.modalPresentationStyle
지정되지 않았습니다..currentContext
.fullScreen
.custom
.overCurrentContext
구성popoverPresentationController
의sourceRect
그리고.sourceView
프레젠테이션 전 다음과 같은 경우:
- 프레젠테이션
UIAlertController
와 함께preferredStyle
의.actionSheet
- 프레젠테이션
UIViewController
와 함께.modalPresentationStyle
다음 중:.popover
.none
이것은 iPhone과 iPad 모두에서 "지정한 모달 프레젠테이션 스타일에 해당 프레젠테이션 컨트롤러가 없습니다."라는 오류와 함께 충돌합니다.
- 프레젠테이션
UIActivityViewController
(https://developer.apple.com/documentation/uikit/uiactivityviewcontroller 을 기준으로 합니다; "iPad에서는 뷰 컨트롤러를 팝업으로 표시해야 합니다. iPhone 및 iPod touch에서는 형식적으로 표시해야 합니다.")
다음은 구성의 예입니다.popoverPresentationController
if let popoverController = popoverPresentationController {
popoverController.sourceView = view
popoverController.sourceRect = CGRect(x: view.bounds.maxX, y: 40, width: 0, height: 0)
}
여기에 설명되지 않은 다른 사례가 발견되면 알려주십시오!
언급URL : https://stackoverflow.com/questions/24224916/presenting-a-uialertcontroller-properly-on-an-ipad-using-ios-8
'programing' 카테고리의 다른 글
배포 인증서/개인 키가 설치되지 않았습니다. (0) | 2023.06.04 |
---|---|
iPhone/iPad용 Javascript 스크롤 이벤트? (0) | 2023.06.04 |
UI WebView에서 HTML 컨텐츠 읽기 (0) | 2023.06.04 |
SQL: 첫 글자만 대문자로 표시 (0) | 2023.06.04 |
활성 레코드를 복제하는 가장 쉬운 방법은 무엇입니까? (0) | 2023.06.04 |