An iOS7 and iOS8 simple alert
来源:互联网 发布:上瘾网络剧在线看 编辑:程序博客网 时间:2024/06/03 14:18
http://coding.tabasoft.it/ios/an-ios7-and-ios8-simple-alert/
In iOS8 the code to show a simple alert to the user is completely changed. UIAlertView is now deprecated:
The new class is UIAlertController and it is not complex to use (more in a minute). But we also want to support our iOS7 users, so wouldn’t it be nice to have a single class handling the different code? This is what we are going to create in this post.
The old way
To show a simple alert with an “OK” button in iOS7 we use this code:
Then we conform our class to the UIAlertViewDelegate protocol and add the method:
This method is called when the button “ok” is pressed. Very simple code and the result is:
This code works right in iOS7 and iOS8 (but it is deprecated in iOS8).
The new way
The new way to do this is in iOS8 is to allocate an UIAlertController, add to it an action relative to the button “OK” and then present the controller using presentViewController.
The result is identical to the previous:
Two notes about the iOS8 code:
- If you run it in iOS7 you cause a crash, so this can be used only if your running device has a system >= iOS8
- A curiosity: in iOS7 you could show an alert from inside viewDidLoad. Now, if you try this, you get a message in the console “Warning: Attempt to present <UIAlertController: 0x7fb219733510> on <ViewController: 0x7fb2196625d0> whose view is not in the window hierarchy!” and nothing happens. It seems that the alert is now a controller and the controller hierarchy is not yet ready. I think this is not a problem and you should not show an alert from viewDidLoad anyway. I showed the alert from the viewDidAppear method.
A single multi-system Alert object
Now we want to create our class that hides the different implementation from our app.
Let’s call it SevenEightAlert. We will invoke it with the common code:
The implementation
In our class we ask for the current version of the system using UIDevice.currentDevice().systemVersion and execute different code depending on it:
Note that for iOS7 we save the closure passed as the third parameter in a property in order to use it later, in the alertView method of the UIAlertViewDelegate.
This code works perfectly on iOS8: we see the alert, press OK and see the log in the console (“alert dismissed”) and the alert disappear graciously.
But when we run it on iOS7 the app just … crashes (with a bad SIGABRT signal). Why?
Alert is Asynchronous
In viewDidAppear we create an instance of SevenEightAlert (calling SevenEightAlert()), then we call show on it and exit from the function. At the time the closure is called (when we press back, some seconds after) that instance does not exist anymore. But that instance was also the delegate of our UIAlertView (remember “delegate = self”) so the app crashes trying to call a delegate object that does not exist anymore.
Not a simple problem, we should try to extend the life of that instance more after the method viewDidAppearreturns. How we can do this?
Welcome the associated object
In iOS we can associate an object to another object.
This is a feature of the Objective-C 2.0 runtime, useful when we want to add a property to another object (of which we don’t have the code), something we cannot do with a category (or swift extension).
To read more about associated object start from this apple document.
If we use associated objects we also extend the length of the life of the object we attach to the length of the life of the object attached (as if it would be a property).
To use associated object we must extend NSObject (because it uses theObjective-C 2.0 runtime).
In the SevenEightAlert.show method, if the system is <= 7 and the action is not nil, we associate ourself to the calling view controller using the objc runtime function objc_setAssociatedObject:
Having declared the two properties:
(assocObjectHandle is simply a key we use as a reference of the association)
We then remove the association after the closure execution in the delegate’s alertView using objc_setAssociatedObject:
And now the code works right also for iOS7 and the callback action is called when the user press “OK”.
You can find the complete code of the class in the GitHub project SevenEightAlert.
And, as usual, if you have comments please feel free to contribute.
- An iOS7 and iOS8 simple alert
- ios7/8 alert and sheet(oc、swift)
- ios7、ios8中的UITableViewCellEditingStyle
- ios7 ios8 Notification
- registerForRemoteNotification iOS7 iOS8
- iOS7,iOS8,iOS9适配
- iOS7与iOS8的比较
- iOS7适配,求iOS8文档
- ios7 ios8 定位兼容性问题解决方案
- 屏幕旋转 iOS7 iOS8 通用版
- iOS7、iOS8的新特性
- qpage.alert - send an alert via QuickPage
- ios8 下面的alert和actionsheet
- A very simple MFC class to Encode and Decode an url string
- ios7 alert中输入单行文本代码
- iOS8正式版系统还原为iOS7.1.2
- iOS8/iOS7对比有什么变化?
- iOS8与iOS7适配问题
- 综合算法02—指定点之间的K短路
- 鸟哥的Linux私房菜笔记
- UltraISO错误提示问题的解决--缺乏权限
- 详细探究Spark的shuffle实现
- android 状态栏、标题栏、屏幕高度
- An iOS7 and iOS8 simple alert
- Building Apps with Over 65K Methods
- 窥探try ... catch与__try ... __except的区别
- MPAndroidChart 教程:ChartData类,ChartData子类, DataSet类,DataSet子类(十二)
- Springmvc构造RESTful详细讲解
- 友盟 微信第三方登录-返回成功却提示服务器繁忙
- HDU 1208 Pascal's Travels(dp)
- 重头开始学JAVA(一)
- 【Java】断言assert及Eclipse、Tomcat 开启断言方式