在iPad中显示类型为UIAlertController
的UIActionSheet
时出现问题。我知道iPad需要更多信息才能显示弹出窗口,但我遇到了一些奇怪的问题。
我正在检查与我的应用程序相关的iOS 13兼容性问题,并且似乎出现了旧技巧,例如使用performSelector
在UIBarButtonItem
上获取视图不再起作用。
方式1
所以我这样做。
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIView* internalView = (UIView*) [weakSelf.navigationItem.rightBarButtonItem performSelector:@selector(view)];
menuController.popoverPresentationController.sourceView = weakSelf.navigationController.navigationBar;
menuController.popoverPresentationController.sourceRect = internalView.frame;
menuController.popoverPresentationController.canOverlapSourceViewRect = YES;
}
internalView
似乎为零,而不是在旧版iOS中获得UIView。弹出窗口显示在屏幕的左上角,而不是导航栏按钮项附近。方式二
因此,我想尝试另一种方式来做到这一点,实际上是“正确的方式”:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
menuController.popoverPresentationController.barButtonItem = weakSelf.navigationItem.rightBarButtonItem;
}
当我尝试使用此代码时,应用程序崩溃,并显示一条消息,提示我必须设置sourceView / sourceRect / barButtonItem。但是我告诉它去做。
由于未捕获的异常“ NSGenericException”而终止应用程序,原因:“您的应用程序呈现了UISmartNavigationController()的UIAlertControllerStyleActionSheet样式的UIAlertController()。具有此样式的UIAlertController的modalPresentationStyle为UIModalPresentationPopover。您必须通过警报控制器的popoverPresentationController提供此弹出窗口的位置信息。您必须提供sourceView和sourceRect或barButtonItem。如果在显示警报控制器时不知道此信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供它。
我也尝试使用
UIPopoverPresentationControllerDelegate
,但得到相同的结果。我检查并重新检查,
weakSelf.navigationItem.rightBarButtonItem
不是零,并设置为右栏按钮项。我想我想念一些巨大的东西,但是呢? 最佳答案
Apple文档参考此页面。
https://developer.apple.com/documentation/uikit/windows_and_screens/displaying_transient_content_in_a_popover
但是,示例代码引用了一个从未定义的对象optionsControl。我可以得到一些构建,部署和运行的变体,但是所有崩溃都会出现类似的错误,例如:
由于出现未捕获的异常'NSGenericException'而终止应用程序,原因:'UIPopoverPresentationController()在演示之前应设置非null的sourceView或barButtonItem。
最后,经过三天的阅读,我发现了此页面UIActivityViewController crashing on iOS 8 iPads,该页面帮助我在下面创建了一个工作版本。这比我尝试过的其他方法简单得多。关键是将控制器的sourceView设置为对我来说是object.view的父视图,因为object是对作为发送方传入的父视图控制器的引用。
static func transmitAirDrop(object: ProjectOrganizerMasterViewController) {
NSLog("UTVCU.transmitAirDrop")
if (StatusReportSettings.supportsAirdrop() == false) {
self.sendMultipleXMLEmail(object: object)
return;
}
let myDelegate : StatusReportAppDelegate = UITableViewController.sharedDelegate()
let documentsDirectory : String = UITableViewController.persistProjectFiles(managedObjectContext: object.managedObjectContext, delegate: myDelegate as! ProjectOrganizerAppDelegate)
let backupZipFileName : String = UITableViewController.backupExportZipFileName(StatusReportSettings.appSpecificFileName())!
let password1 : String = object.passwordPromptController?.textFields?.first?.text ?? ""
let backupZipFilePath : String = StatusReportMasterViewController.createPasswordProtectedExportZipFile(password1: password1, documentsDirectory: documentsDirectory)
let url : URL = URL.init(fileURLWithPath: backupZipFilePath)
NSLog("transmitAirDrop() url ->%@", url.path);
let objectsToShare : NSArray = [url]
NSLog("UTVCU.transmitAirDrop presentViewController calling");
let controller = UIActivityViewController(activityItems: [url], applicationActivities: nil)
controller.excludedActivityTypes = [.postToFacebook,
.postToTwitter,
.print,
.copyToPasteboard,
.assignToContact,
.saveToCameraRoll]
controller.popoverPresentationController?.sourceView = object.view
object.present(controller, animated: true, completion: nil)
NSLog("UTVCU.transmitAirDrop presentViewController returned");
}