iOS Developer

JRAlertController

2016-11-10  本文已影响71人  Jiar_

文章可能有更新,如需了解,请查看原文:JRAlertController


JRAlertController

JRAlertController

JRAlertController:基于apple的UIAlertController控件api,用swift重新打造的UI控件,更符合主流app的风格。

JRAlertController总体效果图

UIAlertController_Main

UIAlertController 历史

在日常iOS开发中,我们经常能遇到这种情况(我们需要在某个地方让用户做一个选择),比如说:一个博客,点击右上角的按钮后,你可以执行“修改博客”、“删除博客”两个操作。既然是这么常用的操作,Apple当然给我们提供了常用的控件,那就是UIAlertController。

UIAlertController自iOS8出现,在那之前,我们用的是UIAlertViewUIActionSheet。iOS8之后,UIAlertViewUIActionSheet合并为UIAlertController,并以一个style属性来区分原来的UIAlertViewUIActionSheet的作用,还有就是用闭包回调的方式代替了之前的代理(我觉得闭包回调的方式写起来方便多了)。

UIAlertController 不足

那么既然UIAlertController已经是在iOS8优化后的控件(至少api上优化了),那么为何还来个JRAlertController呢?


在开发中我们会发现,UIAlertController有以下几个不足之处:

1.无论是alert还是sheet下的界面,边角过于圆滑,尤其当stylesheet的时候,从底部弹出来那么一个过于圆滑的界面,反正我不觉得好看,不信你看微博、微信这些主流app是怎么做的
微博的效果:
[图片上传失败...(image-222eee-1545830231212)]

2.点击背景部分,无法dismiss UIAlertController

3.alert样式下,添加过多的UITextFieldAction后,界面显示丑陋。(虽然不会有这种需求,也不该在UIAlertController过量添加,毕竟UIAlertController适用于"短暂"操作,但是过多添加后,界面确实不好看,后面会有效果图)

基于以上几点不足,我认为足以自定义一个控件来代替UIAlertController,所以JRAlertController诞生了。

JRAlertController 与 UIAlertController 的不同

我在开头提到过UIAlertControllerapi,它的api还是不错的,所以我在写JRAlertController的时候,几乎完全采用了UIAlertControllerapi,一方面api不错,另一方面方便大家从UIAlertController迁移到JRAlertController,基本上你只需要把原来UIAlertController部分的UI开头的改成JR就可以了,我提供的Demo中,大家便能很清晰的看到这一点。


还有的几处不同点:
    // UIAlertController 的初始化方法
    public convenience init(title: String?, message: String?, preferredStyle: UIAlertControllerStyle)

    // JRAlertController 的初始化方法
    public convenience init(title: String? = nil, message: String? = nil, preferredStyle: JRAlertControllerStyle = .actionSheet)

你会发现,JRAlertController提供了title参数和message参数的默认值,恩......如果你不需要titlemessage中的某一个(或都不需要),这样可以帮你少写一点点代码。

    // UIAlertController进入方法
    // 这里的alertController为UIAlertController的实例,self为当前UIViewController
    self.present(alertController, animated: true, completion: nil)

    // JRAlertController进入方法
    // 这里的alertController为JRAlertController的实例,self为当前UIViewController
    alertController.jr_show(onRootView: self)

至于这里为什么要做,这里涉及到JRAlertController从底部上移的动画效果。(目前我能想到的方法是在JRAlertControllerviewWillAppear中执行一个上移动画,如果调用系统的present进入的话,如果又给animated参数设置true,那么JRAlertController的进入效果会比较丑陋。可能有朋友会问,为什么不使用iOS的转场动画,我有尝试去用过,但是也需要第一个执行presentUIViewController做很多其他的动作,写更多的代码。如果有朋友看了我的代码后,有更好的方式来处理进入效果,欢迎到本项目的Github地址Pull requests

UIAlertController里面有一个属性preferredAction,要求系统版本至少为iOS9。而在JRAlertController中,你只需要在iOS8下就可以使用了(如果不是UIViewControllermodalPresentationStyle属性的.overCurrentContext值要求iOS8,我们就可以兼容到iOS7了)

JRAlertController 与 UIAlertController 相同点以及说明

因为JRAlertController是采用几乎和UIAlertController一样的api来实现的,所以JRAlertController的大体功能效果会和UIAlertController一样。同时也是为了方便打算使用JRAlertController的朋友们能够在迁移到JRAlertController的时候没有后顾之忧。


他们的相同点说明:

1.只有alert样式下,才可以添加UITextField

2.action也有样式,但是cancel样式的action只能添加一个,添加多了assert

3.preferredAction属性也只能在alert样式下才能使用。

以上三点别问我为什么这么规定,Apple的UIAlertController就是这么定的。


其他说明:

1.JRAlertControllerpreferredAction属性补充说明:除了只能在alert样式下才能使用外,如果存在UITextField,那么在UITextField列表的最后一个UITextField的键盘中点击return按钮,将触发preferredAction回调,并且dismiss当前JRAlertController

2.JRAlertController里面会有一个属性是这样的:open var textFields: [UITextField]?。所有你添加的UITextField都会在这里。注意的是,JRAlertController已经对所以添加的UITextField进行了代理操作。如果你覆盖了代理,影响也不是很大,但是至少会影响你以下两点:

①.在UITextField中点击键盘上return按钮时无法从当前UITextField进入到下一个UITextField
②.如果当前UITextField已经是最后一个UITextField,同时你又设置了preferredAction,则无法触发preferredAction的回调,以及无法dismiss当前JRAlertController

3.如果需要在JRAlertController里,主动dismiss,建议调用jr_dismiss()

JRAlertController 与 UIAlertController Gif图效果对比

说了那么多,来几张效果图对比下JRAlertControllerUIAlertController的区别

JRAlertController 实现效果图

JRAlertController在alert样式下简单显示
JRAlertController_alert_simple
JRAlertController在alert样式下复杂显示
JRAlertController_alert_multiple
JRAlertController在sheet样式下简单显示
JRAlertController_sheet_simple
JRAlertController在sheet样式下复杂显示
JRAlertController_sheet_multiple

UIAlertController 实现效果图

UIAlertController在alert样式下简单显示
UIAlertController_alert_simple
UIAlertController在alert样式下复杂显示
UIAlertController_alert_multiple
UIAlertController在sheet样式下简单显示
UIAlertController_sheet_simple
UIAlertController在sheet样式下复杂显示
UIAlertController_sheet_multiple

以上就是对JRAlertController的一些说明,下面放是官方性信息:


Requirements

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

CocoaPods 1.1.0+ is required to build JRAlertController 1.0.0

To integrate JRAlertController into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'JRAlertController', '~> 1.0。0'
end

Then, run the following command:

$ pod install

Manually

If you prefer not to use either of the aforementioned dependency managers, you can integrate JRAlertController into your project manually.

Embedded Framework

$ git init


- Add JRAlertController as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following command:

  ```bash
$ git submodule add https://github.com/Jiar/JRAlertController.git

Usage

JRAlertController_alert_simple

        let alertController = JRAlertController(title: "login tip", message: "please input account and password", preferredStyle: .alert)
        let cancelAction = JRAlertAction(title: "cancel", style: .cancel, handler:  {
            (action: JRAlertAction!) -> Void in
            print("cancel")
        })
        let loginAction = JRAlertAction(title: "login", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("login")
        })
        alertController.addAction(cancelAction)
        alertController.addAction(loginAction)
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.keyboardType = .default
            textField.placeholder = "please input account"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.keyboardType = .default
            textField.isSecureTextEntry = true
            textField.placeholder = "please input password"
        })
        // must use this function to show JRAlertController
        // self is a UIControllerView
        alertController.jr_show(onRootView: self)

JRAlertController_alert_multiple

        let alertController = JRAlertController(title: "I am title,I am title,I am title,I am title,I am title", message: "I am message, I am message, I am message, I am message, I am message, I am message, I am message, I am message, I am message", preferredStyle: .alert)
        let cancelAction = JRAlertAction(title: "cancel", style: .cancel, handler:  {
            (action: JRAlertAction!) -> Void in
            print("cancel")
        })
        let deleteAction = JRAlertAction(title: "delete", style: .destructive, handler: {
            (action: JRAlertAction!) -> Void in
            print("delete")
        })
        let archiveAction = JRAlertAction(title: "archive", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive")
        })
        let archiveAction1 = JRAlertAction(title: "archive1", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive1")
        })
        let archiveAction2 = JRAlertAction(title: "archive2", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive2")
        })
        let archiveAction3 = JRAlertAction(title: "archive3", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive3")
        })
        let archiveAction4 = JRAlertAction(title: "archive4", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive4")
        })
        let archiveAction5 = JRAlertAction(title: "archive5", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive5")
        })
        let archiveAction6 = JRAlertAction(title: "archive6", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive6")
        })
        alertController.addAction(cancelAction)
        alertController.addAction(deleteAction)
        alertController.addAction(archiveAction)
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .black
            textField.text = "black"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .darkGray
            textField.text = "darkGray"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .lightGray
            textField.text = "lightGray"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.backgroundColor = .black
            textField.textColor = .white
            textField.text = "white"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .gray
            textField.text = "gray"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .red
            textField.text = "red"
        })
        alertController.addAction(archiveAction1)
        alertController.addAction(archiveAction2)
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .green
            textField.text = "green"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .blue
            textField.text = "blue"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .cyan
            textField.text = "cyan"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .yellow
            textField.text = "yellow"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .magenta
            textField.text = "magenta"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .orange
            textField.text = "orange"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .purple
            textField.text = "purple"
        })
        alertController.addTextField(configurationHandler: { (textField: UITextField) -> Void in
            textField.textColor = .brown
            textField.text = "brown"
        })
        alertController.addAction(archiveAction3)
        alertController.addAction(archiveAction4)
        alertController.addAction(archiveAction5)
        alertController.addAction(archiveAction6)
        alertController.preferredAction  = archiveAction6
        // must use this function to show JRAlertController
        // self is a UIControllerView
        alertController.jr_show(onRootView: self)

JRAlertController_sheet_simple

        let alertController = JRAlertController(title: "blog tip", message: "Please select the option to use the corresponding option to operate your blog", preferredStyle: .actionSheet)
        // let alertController = JRAlertController(title: "blog tip")
        // let alertController = JRAlertController(message: "Please select the option to use the corresponding option to operate your blog")
        // let alertController = JRAlertController()
        let addAction = JRAlertAction(title: "add", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("add blog")
        })
        let modifyAction = JRAlertAction(title: "modify", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("modify blog")
        })
        let deleteAction = JRAlertAction(title: "delete", style: .destructive, handler: {
            (action: JRAlertAction!) -> Void in
            print("delete blog")
        })
        let cancelAction = JRAlertAction(title: "cancel", style: .cancel, handler:  {
            (action: JRAlertAction!) -> Void in
            print("cancel")
        })
        alertController.addAction(addAction)
        alertController.addAction(modifyAction)
        alertController.addAction(deleteAction)
        alertController.addAction(cancelAction)
        // must use this function to show JRAlertController
        // self is a UIControllerView
        alertController.jr_show(onRootView: self)

JRAlertController_sheet_multiple

        let alertController = JRAlertController(title: "I am title,I am title,I am title,I am title,I am title", message: "I am message, I am message, I am message, I am message, I am message, I am message, I am message, I am message, I am message", preferredStyle: .actionSheet)
        let cancelAction = JRAlertAction(title: "cancel", style: .cancel, handler: nil)
        let deleteAction = JRAlertAction(title: "delete", style: .destructive, handler: nil)
        let archiveAction = JRAlertAction(title: "archive", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive")
        })
        let archiveAction1 = JRAlertAction(title: "archive1", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive1")
        })
        let archiveAction2 = JRAlertAction(title: "archive2", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive2")
        })
        let archiveAction3 = JRAlertAction(title: "archive3", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive3")
        })
        let archiveAction4 = JRAlertAction(title: "archive4", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive4")
        })
        let archiveAction5 = JRAlertAction(title: "archive5", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive5")
        })
        let archiveAction6 = JRAlertAction(title: "archive6", style: .default, handler: {
            (action: JRAlertAction!) -> Void in
            print("archive6")
        })
        alertController.addAction(cancelAction)
        alertController.addAction(deleteAction)
        alertController.addAction(archiveAction)
        alertController.addAction(archiveAction1)
        alertController.addAction(archiveAction2)
        alertController.addAction(archiveAction3)
        alertController.addAction(archiveAction4)
        alertController.addAction(archiveAction5)
        alertController.addAction(archiveAction6)
        // must use this function to show JRAlertController
        // self is a UIControllerView
        alertController.jr_show(onRootView: self)

License

JRAlertController is released under the Apache-2.0 license. See LICENSE for details.

结束语

本文完,大家如何喜欢JRAlertController,欢迎来JRAlertController对本项目Star。读者在阅读本文时如有发现错误或不恰当指出,欢迎在评论中指出。如果读者还有一些相关方面的疑问,也欢迎在评论中提出。

欢迎关注我的个人微信订阅号,我将不定期分享开发方面的干货。


Jiar's 微信订阅号
上一篇下一篇

猜你喜欢

热点阅读