Swift UIAlertController-> ActionSheet iPad iOS8 충돌
현재 저는 ActionSheet에 큰 문제가 있습니다. iPhone에서는 잘 작동하지만 iPad에서는 충돌 만 발생합니다.
하나의 버튼으로 새 프로젝트를 만듭니다.
import UIKit
extension ViewController : UIActionSheetDelegate {
func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) {
if actionSheet.tag == 0 {
if buttonIndex == 1 {
// doing something for "product page"
} else if (buttonIndex == 2) {
// doing something for "video"
}
}
}
}
class ViewController: UIViewController, UIActionSheetDelegate {
@IBAction func test(sender: AnyObject) {
let systemVersion: NSInteger = (UIDevice.currentDevice().systemVersion as NSString).integerValue
if systemVersion < 8 {
// iOS7:
let action:UIActionSheet = UIActionSheet(title: "Change Map Type", delegate: self, cancelButtonTitle: "Back", destructiveButtonTitle: nil, otherButtonTitles: "Product Page", "Video")
action.tag = 0
action.showInView(self.view)
} else {
// iOS8:
let alertController: UIAlertController = UIAlertController(title: "Change Map Type", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
let cancelAction: UIAlertAction = UIAlertAction(title: "Back", style: UIAlertActionStyle.Cancel, handler: nil)
let button1action: UIAlertAction = UIAlertAction(title: "Product Page", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) -> () in
// doing something for "product page"
})
let button2action: UIAlertAction = UIAlertAction(title: "Video", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) -> () in
// doing something for "video"
})
alertController.addAction(cancelAction)
alertController.addAction(button1action)
alertController.addAction(button2action)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
내가 아이폰에서 말했듯이 작동하지만 iPad에서 버튼을 클릭하면 앱이 충돌합니다.
2014-09-25 14 : 54 : 52.784 test [9541 : 1970048] * 포착되지 않은 예외 'NSGenericException'으로 인해 앱 종료, 이유 : '애플리케이션이 스타일 UIAlertControllerStyleActionSheet의 UIAlertController ()를 제공했습니다. 이 스타일을 사용하는 UIAlertController의 modalPresentationStyle은 UIModalPresentationPopover입니다. 경고 컨트롤러의 popoverPresentationController를 통해이 팝 오버에 대한 위치 정보를 제공해야합니다. sourceView 및 sourceRect 또는 barButtonItem을 제공해야합니다. 경고 컨트롤러를 표시 할 때이 정보를 알 수없는 경우 UIPopoverPresentationControllerDelegate 메서드 -prepareForPopoverPresentation에서 제공 할 수 있습니다. ' * 첫 번째 호출 스택 : (0 CoreFoundation 0x00613df6 exceptionPreprocess + 182 1 libobjc.A.dylib
0x01fdaa97 objc_exception_throw + 44 2 UIKit
0x0164da37 - [UIPopoverPresentationController presentationTransitionWillBegin] + 3086 3 UIKit
0x00f54f75 __71- [UIPresentationController _initViewHierarchyForPresentationSuperview :] _ block_invoke + 1,666 4 UIKit 0x00f53554 __56- [UIPresentationController runTransitionForCurrentState] _block_invoke + 226 5 UIKit
0x00f8721b __40 + [UIViewController에 _scheduleTransition :] _ block_invoke + 18 6 UIKit 0x00e4d62e ___afterCACommitHandler_block_invoke + 15 7 UIKit 0x00e4d5d9 _applyBlockToCFArrayCopiedToStack + 415 8 UIKit
0x00e4d3ee _afterCACommitHandler + 545 9
Core_Foundation 0x00536fbe __CFRUNLOOP_AN_CALLINGSERVER_OUT_TO_IS_OB+ 30 10 CoreFoundation에서 0x00536f00 __CFRunLoopDoObservers + 400 11 CoreFoundation에서의 0x0052c93a는 __CFRunLoopRun + 1,226 12 CoreFoundation에서 0x0052c1ab CFRunLoopRunSpecific는 + 443 13 CoreFoundation에서
0x0052bfdb CFRunLoopRunInMode는 + 123 14 GraphicsServices
GSEventRunModal + 192 15 GraphicsServices의 0x0438424f
0x0438408c GSEventRun + 104 16 UIKit
0x00e23e16 UIApplicationMain + 1,526 17 시험
0x00085e9e의 top_level_code + 78 18 테스트
0x00085edb 메인 + 43 19 libdyld.dylib
0x0273eac9 시작 + 1 20 ???
0x00000001 0x0 + 1) libc ++ abi.dylib : NSException 유형의 포착되지 않은 예외로 종료
프로젝트는 https://www.dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0 에서 다운로드하여 사용해 볼 수 있습니다 .
오류 메시지는 경보 컨트롤러가 popoverPresentationController
자신을 올바르게 배치 할 수 있도록 위치 를 제공해야 함을 알려줍니다 . 이것은 간단합니다. 팝 오버 컨트롤러가 있는지 확인하고 발신자를 소스로 추가하기 만하면됩니다.
버튼이 다음과 같은 경우 UIBarButtonItem
:
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender
}
self.presentViewController(alertController, animated: true, completion: nil)
그렇지 않으면:
if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = sender
popoverController.sourceRect = sender.bounds
}
self.presentViewController(alertController, animated: true, completion: nil)
이 시도
alertController.popoverPresentationController?.sourceView = self.view
Nate Cook은 완전히 옳지 만 내가 할 것이므로 iPad 또는 iPhone인지 감지합니다.
이것은 barButtonItem
:
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
if let currentPopoverpresentioncontroller = alertController.popoverPresentationController{
currentPopoverpresentioncontroller.barButtonItem = sender as! UIBarButtonItem
currentPopoverpresentioncontroller.permittedArrowDirections = UIPopoverArrowDirection.down;
self.present(alertController, animated: true, completion: nil)
}
}else{
self.present(alertController, animated: true, completion: nil)
}
iPad [ Swift 3+ ] 에서 화살표없이 중앙에 표시하려는 경우 :
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 = []
}
self.present(alertController, animated: true, completion: nil)
누군가 sender : UITapGestureRecognizer를 사용하면 도움이 될 수 있습니다.
@objc func popupSettings(sender : UITapGestureRecognizer) {
.....
if let popoverPresentationController = alert.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = CGRect(origin: sender.location(in: self.view), size: CGSize(width: 1.0, height: 1.0))
}
self.present(alert, animated: true, completion: nil)
}
var actionSheet = UIAlertController(title: "Please Select Camera or Photo Library", message: "", preferredStyle: .actionSheet)
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
actionSheet = UIAlertController(title: "Please Select Camera or Photo Library", message: "", preferredStyle: .alert)
}
actionSheet.addAction(UIAlertAction(title: "Upload a Photo", style: .default, handler: { (UIAlertAction) in
self.openPhotoLibrary()
}))
actionSheet.addAction(UIAlertAction(title: "Take a Photo", style: .default, handler: { (UIAlertAction) in
self.openCamera()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
중앙에 경고를 표시하고 화살표는 표시하지 않으려면 시도해 보았으며 iOS 11.2에서 작동합니다.
신속한 4.2 버전 :
let actionSheet = UIAlertController ......
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){
if let currentPopoverpresentioncontroller = actionSheet.popoverPresentationController{
currentPopoverpresentioncontroller.permittedArrowDirections = []
currentPopoverpresentioncontroller.sourceRect = CGRect(x: (self.view.bounds.midX), y: (self.view.bounds.midY), width: 0, height: 0)
currentPopoverpresentioncontroller.sourceView = self.view
self.present(actionSheet, animated: true, completion: nil)
}
}else{
self.present(actionSheet, animated: true, completion: nil)
}
Objective C 버전 :
UIAlertController* actionSheet
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSArray *empty;
UIPopoverPresentationController *currentPopOverPresentationController = [actionSheet popoverPresentationController];
currentPopOverPresentationController.permittedArrowDirections = empty;
currentPopOverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds), 0, 0);
currentPopOverPresentationController.sourceView = self.view;
[self presentViewController:actionSheet animated:YES completion:nil];
}else{
[self presentViewController:actionSheet animated:YES completion:nil];
}
참고URL : https://stackoverflow.com/questions/26039229/swift-uialertcontroller-actionsheet-ipad-ios8-crashes
'Program Tip' 카테고리의 다른 글
JSON 직렬화 된 데이터를 NSDictionary로 변환하는 방법 (0) | 2020.12.06 |
---|---|
MVC 5 프로젝트에서 jQueryUI 라이브러리를 추가하는 방법은 무엇입니까? (0) | 2020.12.06 |
JSON 개체 목록을 통해 반복 (0) | 2020.12.06 |
에뮬레이터에서 확대 / 축소 할 수 없음 (0) | 2020.12.06 |
단일 연결 목록에서 루프 찾기 (0) | 2020.12.06 |