使用Xcode6-Beta5我已经构建了一个部署目标为7.0的Universal Swift应用程序 . 我构建了一个包含UIActionSheet和UIAlertController的测试应用程序 - 一个按钮选择在运行时调用哪一个 .
首先总结一下:1 . 将8.0内容放入应用程序会导致7.1设备启动失败,即使不执行8.0代码也是如此 . 8.0调用会污染应用程序 . 2. UIActionSheet和UIAlertController都不能在iPad 8.0设备上运行 .
在模拟器中运行:
所有iPhone 8.0目标都可以成功显示UIActionSheet和UIAlertController . 所有iPhone 7.1目标都无法启动UIAlertAction或UIAlertController的符号未找到错误 . 这是一个dyld_fatal_error .
所有iPad 7.1目标都无法启动,就像iPhone 7.1目标失败一样 .
如果我注释掉UIActionController和UIActionAlert代码,那么该应用程序适用于运行UIActionSheet的7.1设备 .
在所有运行UIActionSheet的iPad 8.0目标中都没有显示任何内容,并产生大约80行NSLayoutConstraint问题 . 在所有运行UIActionController的iPad 8.0目标中,将SIGABRT抛出到AppDelegate中:
2014-08-15 10:21:51.799 AlertControllerTest [1828:246107] *由于未捕获的异常终止应用'NSGenericException',原因:'UIPopoverPresentationController (<_UIAlertControllerActionSheetRegularPresentationController: 0x78651780>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.'
-
这些在Xcode6-Beta5中是否仍然被破坏或者我做错了什么?
-
只要不调用8.0函数,是否可以在使用8.0函数构建的7.1应用程序上运行?早期版本曾经以这种方式工作 .
在有人要求查看源代码之前(现在通过GM修改最佳):
@IBAction func tapHereTapped(sender: AnyObject) {
if sheetOrControllerButton.selectedSegmentIndex == 0 {
var actionSheet = UIActionSheet()
actionSheet.addButtonWithTitle("Choice 1")
actionSheet.addButtonWithTitle("Choice 2")
actionSheet.addButtonWithTitle("Choice 3")
actionSheet.addButtonWithTitle("Choice 4")
actionSheet.addButtonWithTitle("Cancel")
if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
actionSheet.addButtonWithTitle("Dummy")
let systemVersion = UIDevice.currentDevice().systemVersion
if NSString(string: UIDevice.currentDevice().systemVersion).doubleValue >= 8 {
//actionSheet.cancelButtonIndex = 4
//actionSheet.cancelButtonIndex = 5
} else {
actionSheet.cancelButtonIndex = 4
}
} else {
actionSheet.cancelButtonIndex = 4
}
actionSheet.title = "Pick a Number"
actionSheet.delegate = self
actionSheet.showInView(self.view)
} else {
var actionSheet:UIAlertController
if sheetOrControllerButton.selectedSegmentIndex == 1 {
actionSheet = UIAlertController(title: "Pick a Number", message: "Why?", preferredStyle: UIAlertControllerStyle.Alert)
} else {
actionSheet = UIAlertController(title: "Pick a Number", message: "Why?", preferredStyle: UIAlertControllerStyle.ActionSheet)
if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
var button = sender as UIButton
actionSheet.popoverPresentationController?.sourceRect = button.bounds
actionSheet.popoverPresentationController?.sourceView = button.viewForBaselineLayout()
}
}
actionSheet.addAction(UIAlertAction(title: "Choice 1", style: UIAlertActionStyle.Default, handler: { (action :UIAlertAction!)in
println("Picked 1")
}))
actionSheet.addAction(UIAlertAction(title: "Choice 2", style: UIAlertActionStyle.Default, handler: { (action :UIAlertAction!)in
println("Picked 2")
}))
actionSheet.addAction(UIAlertAction(title: "Choice 3", style: UIAlertActionStyle.Default, handler: { (action :UIAlertAction!)in
println("Picked 3")
}))
if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: { (action :UIAlertAction!)in
println("Canceled")
}))
} else {
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (action :UIAlertAction!)in
println("Canceled")
}))
}
self.presentViewController(actionSheet, animated: true, completion: nil)
}
}
func actionSheet(theActionSheet: UIActionSheet!, clickedButtonAtIndex buttonIndex: Int) {
if (buttonIndex == 0) {
println("Picked 1")
} else if buttonIndex == 1 {
println("Picked 2")
} else if buttonIndex == 2 {
println("Picked 3")
} else if buttonIndex == 3 {
println("Picked 4")
} else if buttonIndex == 4 {
println("Canceled")
} else {
println("What??")
}
}
我在物理iPhone 4 - 7.1,iPad 2 - 7.1上得到了相同的行为所有8.0测试都在模拟器中 - 我没有在任何设备上放置8.0但又不想让它变硬 .
谢谢大家 .
更新为Beta6:
注意 - 这仍然是模拟器测试 .
我们现在有完整的解决方法来构建一个适用于7.1和8.0的通用应用程序 .
iPhone - 测试iOS版本并根据需要使用UIActionSheet或UIAlertController . .ActionSheet和.Alert样式都适用于8.0 .
iPad 7.1 - UIActionSheet现在"works",但你需要添加一个虚拟的额外按钮 - 它无法显示添加的最后一个按钮 .
iPad 8.0 - UIAlertController .Alert工作,但看起来很糟糕,而.ActionSheet仍然像UIActionSheet一样崩溃 .
更新为Beta7:
没有变化 . iPhone按预期工作 . iPad仍然如上所述 .
通用汽车更新:iPad 8.0的一些改进 . (或者我之前没想过 . )iPhone仍能正常工作 . 包括iPhone 6和iPhone 6 Plus在模拟器中 .
iPad 7.1 - UIActionSheet仍然需要虚拟按钮 . cancelButtonIndex将使文本变暗以指示它是取消按钮,但它不会抵消它 .
iPad 8.0 - UIActionSheet不会崩溃,但不要使用它 . 如果cancelButtonIndex不是-1,则表示列表末尾的按钮显示有问题 . 它可能仍然需要一个虚拟按钮 . 但现在必须将cancelButtonIndex设置为虚拟按钮(不会显示) . 但更糟糕的是,clickedButtonAtIndex被调用两次,一次使用单击按钮,一次使用cancelButtonIndex . 就好像它在行动表关闭时检测到一个虚假 .
iPad 8.0 - 带有.Alert的UIAlertController仍然可以 .
iPad 8.0 - 如果设置了popoverPresentationController sourceRect和sourceView,带有.ActionSheet的UIAlertController现在可以工作 . (之前的情况可能就是这种情况,但是我还有一个问题 - UIAlertActionStyle.Cancel导致按钮消失,所以不要使用它 .
更新为6.0.1:
iPad 7.1 - UIActionSheet仍然需要虚拟按钮 .
iPad 8.0 - 带有.Alert的UIAlertController可以 . 带有UIAlertActionStyle.Cancel的按钮会自动放在按钮列表的底部 .
iPad 8.0 - 带有.ActionSheet的UIAlertController仍然需要设置popoverPresentationController值 . 并且UIAlertActionStyle.Cancel仍然失败 .
总结 - 尚未改进:
iPhone - 所有版本都可以正常工作 - 可以使用UIActionSheet和UIAlertController作为.Alert和.ActionSheet .
iPad 7.1 - UIActionSheet适用于虚拟 .
iPad 8.0 - UIAlertController的工作原理为.Alert和.ActionSheet . 不要使用UIActionSheet .