使用Xib制作简单的AlertView

使用Xib制作简单的AlertView

不仅仅是个AlertView

1.启动Xcode, 新建一个Single View Application, 填写项目名称SimpleAlertView, 点击下一步, 找一个位置存放项目, 完成创建.


使用Xib制作简单的AlertView_第1张图片

2.新建一个Xib文件, 文件名为SimpleAlertView.


使用Xib制作简单的AlertView_第2张图片

3.打开SimpleAlertView.xib文件, 选中view, 对它的属性做一些修改:

修改列表

属性 属性值
Size FreeForm
Status Bar None
Width 280
Height 130

使用Xib制作简单的AlertView_第3张图片

改完之后, view将不会那么巨大......
使用Xib制作简单的AlertView_第4张图片

4.摆放控件

  • Label

拖放两个label到view中, 对label的字体属性分别做以下修改


使用Xib制作简单的AlertView_第5张图片

字体大的做为标题, 小的做为提示信息. 然后分别给两个label增加一些约束, 左图是要给标题label添加的, 右图是针对提示信息label的.


使用Xib制作简单的AlertView_第6张图片

最后选中提示信息label, 修改它的一个属性, 让label中的文字可以适应label的大小.

  • Button

拖两个button到view中, 一个是取消按钮, 另一个是确定按钮.

使用Xib制作简单的AlertView_第7张图片

选中刚刚添加的两个button, 使用StackView对它们进行布局. 选中button之后, 点击设计面板右下角的Stack按钮, 这样就将两个button放在StackView中了.

ok, 现在选中stackView, 只要对它添加一些约束以及修改一两个属性, button就布局好了.
使用Xib制作简单的AlertView_第8张图片

最后只要修改button的一些属性, 所有的布局就完成啦!!!!!!!!

属性 取消按钮 确定按钮
Title Cancle Confirm
Text Color Black White
background(RGB) 235 235 235 149 77 235

完成后的截图如下:

使用Xib制作简单的AlertView_第9张图片

现在进入代码环节

1.创建一个新的类文件, 选择Cocoa Touch Class, 点击下一步. 类的名称为SimpleAlertView, 继承自UIView, 完成创建.

使用Xib制作简单的AlertView_第10张图片

2.打开SimpleAlertView.xib, 把它和刚刚创建的类绑定起来, 这样就可以在SimpleAlertView.swift代码文件中对自定义的SimpleAlertView进行额外的修改.
使用Xib制作简单的AlertView_第11张图片

3.第一次尝试, 看能否把SimpleAlertView显示出来.

  • 打开Main.storyboard, 在设计面板中往ViewController添加一个button, 把button的title改为Show AlertView, 之后打开辅助视图为button关联一个IBAction.


    使用Xib制作简单的AlertView_第12张图片
  • 在showAlertView函数中添加以下的代码段
//加载xib文件, 拿到自定义的SimpleAlertView, 设置大小和位置并添加到根视图中
let alertView = NSBundle.mainBundle().loadNibNamed("SimpleAlertView", owner: nil, options: nil).first as! SimpleAlertView
alertView.frame.size = CGSize(width: 280, height: 130)
alertView.center = self.view.center
self.view.addSubview(alertView)
  • 运行程序, 点击Show AlertView按钮, 可以看到alertView成功创建啦. 截屏效果图...
    使用Xib制作简单的AlertView_第13张图片

    貌似效果不是特别明显, 没关系, 接下来慢慢修饰!!

4.打开SimpleAlertView.xib文件, 再打开辅助视图, 为label和button生成相应的outlei以及action.

import UIKit

class SimpleAlertView: UIView {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var messageLabel: UILabel!
    @IBOutlet weak var cancleButton: UIButton!
    @IBOutlet weak var confirmButton: UIButton!
    
    
    @IBAction func cancle(sender: UIButton) {
    }
    
    @IBAction func confirm(sender: UIButton) {
    }
    
}

5.打开SimpleAlertView.swift代码文件, 在这里可以对SimpleAlertView的外观和行为进行控制.

  • 在confirm IBAction的下方添加 awakeFromNib()函数, 这个函数会在加载xib文件时调用, 可以在这时修改控件的外观.
  • awakeFromNib()函数中添加以下代码
super.awakeFromNib()
//view的位置和大小
self.frame.size = CGSize(width: 280.0, height: 130.0)
self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.midY)
    
//view的阴影
self.layer.shadowColor = UIColor(white: 0, alpha: 1).CGColor
self.layer.shadowOffset = CGSize(width: 0, height: 5)
self.layer.shadowOpacity = 0.5
    
//view的边框
self.layer.borderWidth = 0.3
self.layer.borderColor = UIColor(white: 0, alpha: 0.5).CGColor
    
//设置按钮的圆角
cancleButton.layer.cornerRadius = 5
cancleButton.clipsToBounds = true
confirmButton.layer.cornerRadius = 5
confirmButton.clipsToBounds = true
  • 回到ViewController.swift代码文件中, 修改showAlertView, 将下面两行代码删掉.然后打开Main.storyboard, 将ViewController的view的背景颜色修改为RGB(200, 200, 200)
alertView.frame.size = CGSize(width: 280, height: 130)
alertView.center = self.view.center

6.ok, 现在再一次运行程序, 发现效果比上一次好多了.

使用Xib制作简单的AlertView_第14张图片

7.可不可以有更好的效果呢, 给它加点动画吧.
改变SimpleAlertView的初始位置, 让它一开始在屏幕之外.

self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: -self.frame.size.height)

接着在 awakeFromNib()函数中添加以下代码段, 添加confirmButton.clipsToBounds = true这句代码的下方.

//把view的透明度设为0, 逆时针旋转45度
self.layer.opacity = 0
self.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_4))
    
//持续0.3秒的动画, 实现渐变效果和旋转效果
UIView.animateWithDuration(0.3, animations: { () -> Void in
    self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.midY)
    self.layer.opacity = 1
    self.transform = CGAffineTransformMakeRotation(CGFloat(0))
    }, completion: nil)

运行一遍就可以看到动画效果了!!!!

重点部分, 对按钮的点击做出响应(用3种方式来实现)

第一种方式-----闭包函数

8.awakeFromNib()函数的上方定义两个私有变量, 它们的类型都是(() -> Void)?的闭包.它们分别用来对取消或者确定做出响应.

private var cancleHandler: (() -> Void)?
private var confirmHandler: (() -> Void)?

接着在awakeFromNib()函数的下方定义一个方法, 暴露给外界, 用来设置刚刚定义的私有变量.

    func setActionHandler(actionType: String, handler: () -> Void) {
        
        if actionType == "cancle" {
            cancleHandler = handler
        }else {
            confirmHandler = handler
        }
    }

这里的actionType有两种, cancle或者confirm. 根据第一个参数的值来设置不同的handler.
完成这一步之后, 在生成的IBAction中调用响应的handler.

@IBAction func cancle(sender: UIButton) {   
     UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
            self.layer.opacity = 0
            }) { (_) -> Void in
                if self.cancleHandler == nil {
                    return
                }
                self.cancleHandler!()
        }
    }
    
    @IBAction func confirm(sender: UIButton) {
        UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
            self.layer.opacity = 0
            }) { (_) -> Void in
                if self.confirmHandler == nil {
                    return
                }
                self.confirmHandler!()
        }
    }

这两个IBAction都先把SimpleAlertView移到屏幕的下方, 在完成这个动画之后就会执行相应的handler.
到现在为止, SimpleAlertView.swift的完整代码如下:

import UIKit

class SimpleAlertView: UIView {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var messageLabel: UILabel!
    @IBOutlet weak var cancleButton: UIButton!
    @IBOutlet weak var confirmButton: UIButton!
    
    private var cancleHandler: (() -> Void)?
    private var confirmHandler: (() -> Void)?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        //view的位置和大小
        self.frame.size = CGSize(width: 280.0, height: 130.0)
        self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: -self.frame.size.height)
        
        //view的阴影
        self.layer.shadowColor = UIColor(white: 0, alpha: 1).CGColor
        self.layer.shadowOffset = CGSize(width: 0, height: 5)
        self.layer.shadowOpacity = 0.5
        
        //view的边框
        self.layer.borderWidth = 0.3
        self.layer.borderColor = UIColor(white: 0, alpha: 0.5).CGColor
        
        //设置按钮的圆角
        cancleButton.layer.cornerRadius = 5
        cancleButton.clipsToBounds = true
        confirmButton.layer.cornerRadius = 5
        confirmButton.clipsToBounds = true
        
        //把view的透明度设为0, 逆时针旋转45度
        self.layer.opacity = 0
        self.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI_4))
        
        //持续0.3秒的动画, 实现渐变效果和旋转效果
        UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.midY)
            self.layer.opacity = 1
            self.transform = CGAffineTransformMakeRotation(CGFloat(0))
            }, completion: nil)
    }
    
    func setActionHandler(actionType: String, handler: () -> Void) {
        
        if actionType == "cancle" {
            cancleHandler = handler
        }else {
            confirmHandler = handler
        }
    }
    
    @IBAction func cancle(sender: UIButton) {
        UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
            self.layer.opacity = 0
            }) { (_) -> Void in
                if self.cancleHandler == nil {
                    return
                }
                self.cancleHandler!()
        }
    }
    
    @IBAction func confirm(sender: UIButton) {
        UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
            self.layer.opacity = 0
            }) { (_) -> Void in
                if self.confirmHandler == nil {
                    return
                }
                self.confirmHandler!()
        }
    }
    
}

接下来, 回到ViewController.swift代码文件, 在showAlertView() IBAction中添加以下代码, 来验证闭包函数是否有备执行到.

alertView.setActionHandler("cancle") { () -> Void in
    print("test")
    alertView.removeFromSuperview()
}

点击cancle按钮, 可以看到SimpleAlertView逐渐往屏幕下方淡出, 而且在控制打印出了test.


这里的handler闭包只是简单把SimpleAlertView移除, 可以根据实际情况做更多的事.

第二种方式-----通知

9.首先注释掉刚刚在showAlertView()添加的代码, 以及在cancle(sender: UIButton), confirm(sender: UIButton)中的所有代码.
然后在cancle(sender: UIButton)中添加下面这行代码. 这行代码的作用是发一个通知, 第一个参数是通知的名称, 最后一个参数是附加信息.

NSNotificationCenter.defaultCenter().postNotificationName("buttonClick", object: nil, userInfo: ["actionType": "cancle"])

同样在onfirm(sender: UIButton)中添加一行类似的代码.

NSNotificationCenter.defaultCenter().postNotificationName("buttonClick", object: nil, userInfo: ["actionType": "confirm"])

回到ViewController.swift代码文件, 在viewDidLoad()中添加一行代码, 让ViewController成为这个消息的接收者.

NSNotificationCenter.defaultCenter().addObserver(self, selector: "receiveNotification:", name: "buttonClick", object: nil)

在接收到通知之后就会调用receiveNotification()函数, 可以在这个函数里面做出对应的响应. 这个函数现在实现如下:

func receiveNotification(notification: NSNotification) {
            
        let alertView = self.view.viewWithTag(101) as! SimpleAlertView
        
        let action = notification.userInfo!["actionType"] as! String
        
        if action == "cancle" {
            
            UIView.animateWithDuration(0.3, animations: { () -> Void in
                alertView.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
                alertView.layer.opacity = 0
                }) { (_) -> Void in
                    alertView.removeFromSuperview()
            }
            
        }else {
            alertView.removeFromSuperview()
        } 
    }

为了让这段代码能够执行, 还要把alertView的tag设置为101. 在showAlertView(sender: UIButton)中添加这行代码.

alertView.tag = 101

ok, 运行一次程序, 效果和第一种方式类似.

第三种方式-----代理

10.注释掉viewDidLoad()中的那行接收通知的代码.打开SimpleAlertView.swift代码文件, 在import UIKit的下方定义一个协议.

@objc protocol SimpleAlertViewDelegate {
    optional func simpleAlertView(actionType: String)
}

在awakeFromNib()函数的上方定义一个代理变量.

var delegate: SimpleAlertViewDelegate!

注释掉cancle(sender: UIButton), confirm(sender: UIButton)中发送通知的代码.
在cancle(sender: UIButton)中添加这行代码.

delegate.simpleAlertView!("cancle")

在confirm(sender: UIButton)中添加响应的代码.

delegate.simpleAlertView!("confirm")

回到ViwController.swift代码文件, 让ViewController实现SimpleAlertViewDelegate.
在ViewController的最下方的大括号之外, 添加以下代码段.

extension ViewController: SimpleAlertViewDelegate {
    func simpleAlertView(action: String) {
        
        let alertView = self.view.viewWithTag(101) as! SimpleAlertView
        
        if action == "cancle" {
            
            UIView.animateWithDuration(0.3, animations: { () -> Void in
                alertView.center = CGPoint(x: UIScreen.mainScreen().bounds.midX, y: UIScreen.mainScreen().bounds.maxY)
                alertView.layer.opacity = 0
                }) { (_) -> Void in
                    alertView.removeFromSuperview()
            }
            
        }else {
            alertView.removeFromSuperview()
        }
    }
}

最后在showAlertView(sender: UIButton)中添加一行代码, 让ViewController成为SimpleAlertView的代理人.

alertView.delegate = self

到这里就完成这个demo了.

demo的地址SimpleAlertView

你可能感兴趣的:(使用Xib制作简单的AlertView)