上代码
//
// TGAnimationButton.swift
// TGAnimationButton
//
// Created by targetcloud on 2017/8/18.
// Copyright © 2017年 targetcloud. All rights reserved.
//
import UIKit
enum TGAnimationButtonKind {
case topToBottom
case bottomToTop
case leftToRight
case rightToLeft
case scale
}
class TGAnimationButton: UIButton {
var animationKind: TGAnimationButtonKind = .topToBottom
var borderColor: UIColor = UIColor.clear {
didSet {
layer.borderColor = borderColor.cgColor
}
}
var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
public override var isEnabled: Bool {
didSet {
if oldValue != isEnabled {
if oldValue {
lastDisabledTitle = title(for: .disabled)
loading(title: lastDisabledTitle)
setTitle("", for: .disabled)
} else {
reset()
setTitle(lastDisabledTitle, for: .disabled)
}
}
}
}
lazy var backV = UIView()
lazy var messageLbl = UILabel()
lazy var indicatorV: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView()
indicator.hidesWhenStopped = true
indicator.sizeToFit()
indicator.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
return indicator
}()
private var lastTitle: String?
private var lastDisabledTitle: String?
private var lastWidth: CGFloat?
private var lsatHeight: CGFloat?
private let margin: CGFloat = 8
private var transformY: CGFloat {
return self.h * (animationKind == .topToBottom ? (-1) : (animationKind == .bottomToTop ? 1 : 0))
}
private var transformX: CGFloat {
return self.w * (animationKind == .leftToRight ? (-1) : (animationKind == .rightToLeft ? 1 : 0))
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
layer.masksToBounds = true
messageLbl.textColor = titleLabel?.textColor
messageLbl.font = titleLabel?.font
backV.addSubview(messageLbl)
indicatorV.activityIndicatorViewStyle = .gray
backV.addSubview(indicatorV)
backV.h = self.h
backV.centerY = self.h * 0.5
backV.backgroundColor = .clear
backV.alpha = 0
addSubview(backV)
lastTitle = currentTitle
lsatHeight = self.h
lastWidth = self.w
}
private func loading(title: String?) {
messageLbl.text = title
messageLbl.textColor = self.titleColor(for: .disabled)
messageLbl.shadowColor = self.titleShadowColor(for: .disabled)
messageLbl.font = self.titleLabel?.font
messageLbl.sizeToFit()
indicatorV.centerY = backV.centerY
indicatorV.x = margin
messageLbl.centerY = indicatorV.centerY
messageLbl.left = indicatorV.right + margin
backV.right = messageLbl.right
backV.w = messageLbl.right + margin
self.w = self.w < backV.w ? backV.w : self.w
backV.left = (self.w - backV.w ) * 0.5
indicatorV.startAnimating()
backV.transform = (title == lastTitle) ? .identity : animationKind == .scale ? CGAffineTransform(scaleX: 0.5, y: 0.5) : CGAffineTransform(translationX: transformX, y: transformY)
UIView.animate(withDuration: 0.5) {
self.titleLabel!.alpha = 0
self.backV.alpha = 1
self.backV.transform = .identity
}
}
private func reset() {
UIView.animate(withDuration: 0.5, animations: {
self.titleLabel!.alpha = 1
self.backV.alpha = 0
self.backV.transform = (self.currentTitle == self.lastDisabledTitle) ? .identity : self.animationKind == .scale ? CGAffineTransform(scaleX: 0.5, y: 0.5) : CGAffineTransform(translationX: 0, y: self.transformY)
}) { (finished) in
self.backV.transform = .identity
self.indicatorV.stopAnimating()
UIView.animate(withDuration: 0.5, animations: {
if self.currentTitle == self.lastDisabledTitle {
self.w = self.lastWidth ?? self.w
}else{
self.sizeToFit()
self.w = self.w > (self.lastWidth ?? self.w) ? self.w : (self.lastWidth ?? self.w)
self.h = self.lsatHeight ?? self.h
}
})
}
}
}
//
// UIView+extension.swift
// TGAnimationButton
//
// Created by targetcloud on 2017/8/18.
// Copyright © 2017年 targetcloud. All rights reserved.
//
import UIKit
extension UIView {
func clipRectCorner(direction: UIRectCorner, cornerRadius: CGFloat) {
let cornerSize = CGSize(width: cornerRadius, height: cornerRadius)
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: direction, cornerRadii: cornerSize)
let maskLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.path = maskPath.cgPath
layer.addSublayer(maskLayer)
layer.mask = maskLayer
}
public var x: CGFloat{
get{
return self.frame.origin.x
}
set{
var r = self.frame
r.origin.x = newValue
self.frame = r
}
}
public var left: CGFloat{
get{
return self.frame.origin.x
}
set{
var r = self.frame
r.origin.x = newValue
self.frame = r
}
}
public var y: CGFloat{
get{
return self.frame.origin.y
}
set{
var r = self.frame
r.origin.y = newValue
self.frame = r
}
}
public var rightX: CGFloat{
get{
return self.x + self.width
}
set{
var r = self.frame
r.origin.x = newValue - frame.size.width
self.frame = r
}
}
public var right: CGFloat{
get{
return self.x + self.width
}
set{
var r = self.frame
r.origin.x = newValue - frame.size.width
self.frame = r
}
}
public var bottomY: CGFloat{
get{
return self.y + self.height
}
set{
var r = self.frame
r.origin.y = newValue - frame.size.height
self.frame = r
}
}
public var bottom: CGFloat{
get{
return self.y + self.height
}
set{
var r = self.frame
r.origin.y = newValue - frame.size.height
self.frame = r
}
}
public var centerX : CGFloat{
get{
return self.center.x
}
set{
self.center = CGPoint(x: newValue, y: self.center.y)
}
}
public var centerY : CGFloat{
get{
return self.center.y
}
set{
self.center = CGPoint(x: self.center.x, y: newValue)
}
}
public var width: CGFloat{
get{
return self.frame.size.width
}
set{
var r = self.frame
r.size.width = newValue
self.frame = r
}
}
public var w: CGFloat{
get{
return self.frame.size.width
}
set{
var r = self.frame
r.size.width = newValue
self.frame = r
}
}
public var height: CGFloat{
get{
return self.frame.size.height
}
set{
var r = self.frame
r.size.height = newValue
self.frame = r
}
}
public var h: CGFloat{
get{
return self.frame.size.height
}
set{
var r = self.frame
r.size.height = newValue
self.frame = r
}
}
public var origin: CGPoint{
get{
return self.frame.origin
}
set{
self.x = newValue.x
self.y = newValue.y
}
}
public var size: CGSize{
get{
return self.frame.size
}
set{
self.width = newValue.width
self.height = newValue.height
}
}
}
//
// ViewController.swift
// TGAnimationButton
//
// Created by targetcloud on 2017/8/18.
// Copyright © 2017年 targetcloud. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
private lazy var loginButton: TGAnimationButton = {
let btn = TGAnimationButton(frame: CGRect(x: 50, y: 50, width: 80, height: 50))
btn.backgroundColor = UIColor.green.withAlphaComponent(0.5)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 15)
btn.setTitleColor(.darkGray, for: .normal)
btn.setTitleColor(.darkGray, for: .disabled)
btn.cornerRadius = 5
btn.borderColor = .darkGray
btn.borderWidth = 1
btn.animationKind = .scale
btn.setTitle("登录", for: .normal)
btn.setTitle("登录中...", for: .disabled)
btn.addTarget(self, action: #selector(click), for: .touchUpInside)
return btn
}()
func click() {
loginButton.isEnabled = false
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3.0) {
self.loginButton.isEnabled = true
//self.loginButton.setTitle("登陆成功了了了了了了了了了了了了了了了了", for: .normal)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(loginButton)
}
}