UIAlertView/UIAlertController iOS 7和iOS 8兼容性
我正在使用Swift编写应用程序,我需要显示警报。应用程序必须与iOS 7和iOS 8兼容。由于UIAlertView/UIAlertController iOS 7和iOS 8兼容性,ios,swift,uialertview,uialertcontroller,Ios,Swift,Uialertview,Uialertcontroller,我正在使用Swift编写应用程序,我需要显示警报。应用程序必须与iOS 7和iOS 8兼容。由于UIAlertView已被UIAlertController替换,我如何在不检查系统版本的情况下检查UIAlertController是否可用?我一直听说苹果建议我们不要为了确定API的可用性而检查设备的系统版本 这是我在iOS 8上使用的,但在iOS 7上会崩溃,出现“dyld:Symbol not found:\u OBJC\u CLASS\u$\ u UIAlertAction”: 如果我使用i
UIAlertView
已被UIAlertController
替换,我如何在不检查系统版本的情况下检查UIAlertController
是否可用?我一直听说苹果建议我们不要为了确定API的可用性而检查设备的系统版本
这是我在iOS 8上使用的,但在iOS 7上会崩溃,出现“dyld:Symbol not found:\u OBJC\u CLASS\u$\ u UIAlertAction
”:
如果我使用iOS 8的UIAlertView,我会收到以下警告:
警告:尝试在演示或取消过程中从视图控制器取消代码>如果您想与iOS 7兼容,请不要使用UIAlertController
。就这么简单
UIAlertView
尚未被替换,它仍能正常工作,并在可预见的未来继续正常工作。您可以使用以下代码解决问题:-
var device : UIDevice = UIDevice.currentDevice()!;
var systemVersion = device.systemVersion;
var iosVerion : Float = systemVersion.bridgeToObjectiveC().floatValue;
if(iosVerion < 8.0) {
let alert = UIAlertView()
alert.title = "Noop"
alert.message = "Nothing to verify"
alert.addButtonWithTitle("Click")
alert.show()
}else{
var alert : UIAlertController = UIAlertController(title: "Noop", message: "Nothing to verify", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style:.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
var-device:UIDevice=UIDevice.currentDevice()!;
var systemVersion=device.systemVersion;
var iosVerion:Float=systemVersion.bridgeToObjectiveC().floatValue;
如果(IOSVRION<8.0){
let alert=UIAlertView()
alert.title=“Noop”
alert.message=“无需验证”
alert.addButtonWithTitle(“单击”)
alert.show()
}否则{
var-alert:UIAlertController=UIAlertController(标题:“Noop”,消息:“无需验证”,首选样式:UIAlertControllerStyle.alert)
addAction(UIAlertAction(标题:“单击”,样式:。默认,处理程序:nil))
self.presentViewController(警报、动画:true、完成:nil)
}
UIKit必须标记为可选的,而不是必需的
考特西:-检测模式与Objective-C样式相同
您需要检测当前活动运行时是否能够实例化此类
if objc_getClass("UIAlertController") != nil {
println("UIAlertController can be instantiated")
//make and use a UIAlertController
}
else {
println("UIAlertController can NOT be instantiated")
//make and use a UIAlertView
}
不要试图根据操作系统版本来解决这个问题。你需要检测能力而不是操作系统
编辑
此答案的原始检测器NSClassFromString(“UIAlertController”)
在-O
优化下失败,因此其已更改为当前版本,该版本适用于发布版本
编辑2
NSClassFromString
正在进行Xcode 6.3/Swift 1.2中的所有优化,对于非Swift代码,纯objective-C可以这样做
if ([UIAlertController class])
{
// use UIAlertController
UIAlertController *alert= [UIAlertController
alertControllerWithTitle:@"Enter Folder Name"
message:@"Keep it short and sweet"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
//Do Some action here
UITextField *textField = alert.textFields[0];
NSLog(@"text was %@", textField.text);
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSLog(@"cancel btn");
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = @"folder name";
textField.keyboardType = UIKeyboardTypeDefault;
}];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
// use UIAlertView
UIAlertView* dialog = [[UIAlertView alloc] initWithTitle:@"Enter Folder Name"
message:@"Keep it short and sweet"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
dialog.alertViewStyle = UIAlertViewStylePlainTextInput;
dialog.tag = 400;
[dialog show];
}
您可以使用一个类别来解决这个问题(尽管您需要将其转换为Swift):
但是,如果不想检查系统版本,只需使用
BOOL lowerThaniOS8 = NSClassFromString( @"UIAlertController" ) == nil;
在iOS8的UIView(AlertCompatibility)类别中,有一个新的类UIAlertController
,它取代了UIAlertView
和UIActionSheet
。从iOS8开始,使用UIAlertController;对于iOS8,在使用UIAlertView和UIActionSheet之前。我认为iOS8增加了size类
,它们改变了UIAlertView
的显示方向。请参阅:我很恼火,因为我一直在写这两种情况,所以我写了一个兼容的UIAlertController,它也适用于iOS 7,所以我把它放到GitHub上。我尽了最大努力复制添加UIAlertController按钮和操作的方法(更好)。与Objective-C和Swift一起工作。我在谷歌上搜索时发现了这个问题,并认为这可能对其他人有所帮助
从此服务器下载警报类
并且可以轻松地在ios 6、7和8上使用它
//Old code
**UIAlertView** *alert=[[**UIAlertView** alloc]initWithTitle:@"FreeWare" message:@"Welcome to Common class" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
//New code
**MyAlertView** *alert=[[**MyAlertView** alloc]initWithTitle:@"FreeWare" message:@"Welcome to Common class" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
以下是我的拖放swift解决方案:
//Alerts change in iOS8, this method is to cover iOS7 devices
func CozAlert(title: String, message: String, action: String, sender: UIViewController){
if respondsToSelector("UIAlertController"){
var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: action, style: UIAlertActionStyle.Default, handler:nil))
sender.presentViewController(alert, animated: true, completion: nil)
}
else {
var alert = UIAlertView(title: title, message: message, delegate: sender, cancelButtonTitle:action)
alert.show()
}
}
这样称呼:
CozAlert("reportTitle", message: "reportText", action: "reportButton", sender: self)
请注意,这仅适用于最基本的警报,您可能需要额外的高级代码。如果您如上所述同时使用iOS 7-UIAlertView和iOS 8+UIAlertController,并且希望UIAlertController块调用UIAlertView的委托(例如MyController)alertView:didDismissWithButtonIndex方法继续处理结果,下面是一个如何执行此操作的示例:
if ([UIAlertController class]) {
MyController * __weak mySelf = self;
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:alertCancel
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
[mySelf alertView:nil didDismissWithButtonIndex:0];
}
];
...
这使用了苹果关于在块中捕捉自我的建议:
当然,此方法假定控制器中只有一个UIAlertView,因此将nil作为其值传递给委托方法。否则,您需要实例化(并标记)一个“假”UIAlertView以传递给alertView:didDismissWithButtonIndex。如果这是共享代码,并且该代码可能用于iOS 8扩展(其中UIAlertView和UIActionSheet是受限制的API)以及iOS 7,其中UIAlertController不存在,看看:
它是UIAlertController到iOS 7的一个API兼容的后端端口,我承诺使SDK代码在iOS 7和iOS 8扩展中都能安全使用。Swift 2.0
if #available(iOS 8.0, *) {
} else {
}
这里检查UIAlertView
和的两种方式
检查1:iOS版本检查类
检查2:检查UIAlertController
nil,然后检查8.0以下的iOS版本
if objc_getClass("UIAlertController") != nil {
// UIALertController
let alert = UIAlertController(title: "Alert", message: "Alert after 8.0", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
}
else {
// UIALertView
UIAlertView(title: "Alert", message: "Alert below iOS V 8.0", delegate: nil, cancelButtonTitle: "OK").show()
}
试试下面的代码。它适用于iOS 8及以下版本
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}
但我在iOS 8设备上运行时收到以下警告:警告:在演示或取消过程中尝试从视图控制器取消!那么提交一份bug报告?iOS 8是一个测试版,它有漏洞。我(ab)使用UIAlertView作为密码双输入类型,两个编辑框必须匹配。我通过将子视图添加到更大的视图中,然后将该视图添加为警报视图的附件视图来实现这一点。不幸的是,视图的大小被截断,第二个编辑框被完全删除,按钮也被完全删除。@Eric不推荐使用,但仅在文档中,他们故意没有在头文件中将其标记为不推荐使用。通常,苹果这样做意味着他们想要pe
if #available(iOS 8.0, *) {
} else {
}
if #available(iOS 8.0, *) {
// UIALertController
let alert = UIAlertController(title: "Alert", message: "Alert after 8.0", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
} else {
// UIALertView
UIAlertView(title: "Alert", message: "Alert below iOS V 8.0", delegate: nil, cancelButtonTitle: "OK").show()
}
if objc_getClass("UIAlertController") != nil {
// UIALertController
let alert = UIAlertController(title: "Alert", message: "Alert after 8.0", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
}
else {
// UIALertView
UIAlertView(title: "Alert", message: "Alert below iOS V 8.0", delegate: nil, cancelButtonTitle: "OK").show()
}
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}