swift view 和 uiview_Swift 全局提示hud

功能特色

  1. 无需初始化和区分主线程
  2. 信息提示
  3. 加载中动画
  4. 自动显示UITableView无数据展示空白界面
  5. Window级别展示
  6. 高斯模糊效果
  7. 提示显示中不卡屏

dbc7bf2577dc43751d7e74f2f7c4bc81.gif
CupidLoud/DCLoadingV​github.com
f87b4714b156a564dc5871458e8e5b10.png
//
//  DCLoadingV.swift
//
//
//  Created by nn on 2017/10/24.
//
//

import UIKit

private var loadingV: DCLoadingV!//转圈
private var topMesV: DCLoadingV!//主要用于显示提示, 不会受DCLoadingV.Disapear()的影响
private var blankV: DCLoadingV!//UITableView无数据展示页面

class DCLoadingV: UIView {
    
    /*
     DCLoadingV.Showing() 显示加载中视图
     DCLoadingV.ShowMes(mes, after: 1.5)  显示提示信息, 1.5秒后自动隐藏
     DCLoadingV.Disapear() 隐藏加载中视图
     */
    
    @objc class func Showing(_ isCanDo: Bool = true) {//true 加载时能操作
        DCLoadingV.bitInit()
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
            blankV.removeFromSuperview()
            if loadingV.alpha == 1 {
                return
            }
            
            loadingV.addAnimat()
            loadingV.isUserInteractionEnabled = !isCanDo
            
            loadingV.nameV.alpha = 0
            loadingV.hudV.alpha = 1
            loadingV.alpha = 1
            loadingV.frame = winBounds
            
            _Window().addSubview(loadingV)
        }
    }
    
    @objc class func Disapear() {//取消显示
        DCLoadingV.bitInit()
        
        DispatchQueue.main.async {
            loadingV.alpha = 0
            loadingV.removeFromSuperview()
            loadingV.removeAnimat()
            DCLoadingV.BlankDo()
        }
    }
    
    
    @objc class func BlankDo() {//无数据
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {//特殊无需此操作VC
            if "ChatDetailVC SeeDoctorOffLineVC SeeDoctorManagerVC SeeDoctorOnLineVC".contains("(type(of: _vc!))") {
                return
            }
            
            blankV.isUserInteractionEnabled = false
            blankV.hudV.alpha = 0
            blankV.nameV.alpha = 1
            blankV.nameV.backgroundColor = UIColor.clear
            blankV.blurV.alpha = 0
            blankV.alpha = 0
            
            blankV.nameL.text = "这里空空如也.."
            blankV.nameL.textColor = UIColor.lightGray
            blankV.nameL.font = UIFont.systemFont(ofSize: 15)
            blankV.imgV.image = UIImage.init(named: "无数据")
            
            var inV = _vc.view
            for vv in _vc.view.subviews {
                if vv.isKind(of: UITableView.self) && vv.frame.width >= winW*0.75 && vv.frame.height >= winH*0.5 {
                    inV = vv
                }
            }
            
            if inV!.isKind(of: UITableView.self) {
                let tv = inV as! UITableView
                if tv.visibleCells.isEmpty {
                    blankV.frame = CGRect(x: 0, y: 0, width: inV!.frame.width, height: inV!.frame.width)
                    inV!.addSubview(blankV)
                    UIView.animate(withDuration: 0.2, animations: {
                        blankV.alpha = 1
                    })
                }
            }
        }
    }
    
    
    @objc class func ShowMes(_ mes: String?) {
        DCLoadingV.ShowMes(mes, after: 2)
    }
    
    @objc class func ShowMes(_ mes: String?, after: Double) {//显示提示
        let mes = mes ?? ""
        print("打印消息", mes)
        
        if mes != "" {
            DCLoadingV.Disapear()
            
            DispatchQueue.main.async {
                topMesV.isUserInteractionEnabled = false
                topMesV.hudV.alpha = 0
                topMesV.nameV.alpha = 1
                topMesV.alpha = 1
                
                topMesV.nameL.text = mes
                topMesV.frame = CGRect(x: 0, y: 0, width: winW/2.1, height: winW/2.1)
                topMesV.center = CGPoint.init(x: winW/2, y: winH/2)
                topMesV.nameL.font = UIFont.boldSystemFont(ofSize: 15)
                _Window().addSubview(topMesV)
                
                if topMesV.lastMesTime + after > DispatchTime.now() {
                    MCGCDTimer.shared.cancleTimer(WithTimerName: "topMesV")
                }
                MCGCDTimer.shared.scheduledDispatchTimer(WithTimerName: "topMesV", timeInterval: after, queue: DispatchQueue.main, repeats: false, atOnce: false) {
                    topMesV.alpha = 0
                    topMesV.removeFromSuperview()
                }
                topMesV.lastMesTime = DispatchTime.now()
            }
        }
    }
    
    
    private class func bitInit() {//初始化
        if loadingV == nil {
            DispatchQueue.main.async {
                loadingV = (Bundle.main.loadNibNamed("DCLoadingV", owner: nil, options: nil)?.last as! DCLoadingV)
            }
        }
        
        if topMesV == nil {
            DispatchQueue.main.async {
                topMesV = (Bundle.main.loadNibNamed("DCLoadingV", owner: nil, options: nil)?.last as! DCLoadingV)
            }
        }
        
        if blankV == nil {
            DispatchQueue.main.async {
                blankV = (Bundle.main.loadNibNamed("DCLoadingV", owner: nil, options: nil)?.last as! DCLoadingV)
            }
        }
    }
    
    
    override func awakeFromNib() {
        super.awakeFromNib()
        alpha = 0
        decotate(textC: nil, cornerR: 10, borderC: nil, borderW: nil)
        
        block1.decotate(textC: nil, cornerR: 7.5, borderC: nil, borderW: nil)
        block2.decotate(textC: nil, cornerR: 7.5, borderC: nil, borderW: nil)
        block3.decotate(textC: nil, cornerR: 7.5, borderC: nil, borderW: nil)
    }
    
    private func addAnimat() {
        let vs = [block1, block2, block3]
        for idx in 0..<vs.count {
            UIView.animate(withDuration: 0.4, delay: 0.4*(Double(idx)/2), options: [.repeat, .autoreverse], animations: {
                vs[idx]!.transform = CGAffineTransform.init(scaleX: 0.5, y: 0.5)
            })
        }
    }
    
    private func removeAnimat() {
        let vs = [block1, block2, block3]
        for idx in 0..<vs.count {
            vs[idx]!.transform = CGAffineTransform.identity
        }
    }
    
    @IBOutlet weak var nameV: UIView!
    @IBOutlet weak var imgV: UIImageView!
    @IBOutlet weak var blurV: UIVisualEffectView!
    @IBOutlet weak var nameL: UILabel!
    
    @IBOutlet weak var hudV: UIView!
    @IBOutlet weak var block1: UIImageView!
    @IBOutlet weak var block2: UIImageView!
    @IBOutlet weak var block3: UIImageView!
    
    var lastMesTime = DispatchTime.now()
    
}


//MARK: 工具
class MCGCDTimer {
    
    func scheduledDispatchTimer(WithTimerName name: String?, timeInterval: Double, queue: DispatchQueue, repeats: Bool, atOnce: Bool, action: @escaping()->()) {//atOnce是否立即执行
        if name == nil {
            return
        }
        var timer = timerContainer[name!]
        if timer == nil {
            timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
            timer?.resume()
            timerContainer[name!] = timer
        }
        
        timer?.schedule(deadline: .now()+(atOnce ? 0 : timeInterval), repeating: timeInterval, leeway: DispatchTimeInterval.milliseconds(100))//精度0.1秒
        timer?.setEventHandler(handler: { [weak self] in
            action()
            if repeats == false {
                self?.cancleTimer(WithTimerName: name)
            }
        })
    }
    
    func cancleTimer(WithTimerName name: String?) {
        let timer = timerContainer[name!]
        if timer == nil {
            return
        }
        timerContainer.removeValue(forKey: name!)
        timer?.cancel()
    }
    
    func isExistTimer(WithTimerName name: String?) -> Bool {
        if timerContainer[name!] != nil {
            return true
        }
        return false
    }
    
    static let shared = MCGCDTimer()
    lazy var timerContainer = [String: DispatchSourceTimer]()
    
}


func _Window() -> UIWindow {//获取最顶层可用Window
    for win in UIApplication.shared.windows.reversed() {
        if win.isOpaque && !win.isHidden && win.alpha > 0 && win.isKind(of: NSClassFromString("UITextEffectsWindow")!.self) {
            return win
        }
    }
    return UIApplication.shared.keyWindow!
}

extension UIView {
    func decotate(textC: UIColor?, cornerR: CGFloat?, borderC: UIColor?, borderW: CGFloat?) {//圆角
        self.layer.masksToBounds = true
        if textC != nil {
            if self.isKind(of: UIButton.self) {
                (self as! UIButton).setTitleColor(textC, for: .normal)
            }
            if self.isKind(of: UILabel.self) {
                (self as! UILabel).textColor = textC
            }
        }
        if cornerR != nil {
            self.layer.cornerRadius = cornerR!
        }
        if borderC != nil {
            self.layer.borderColor = borderC!.cgColor
        }
        if borderW != nil {
            self.layer.borderWidth = borderW!
        }
    }
}

extension String {
    static func randomStr(len: Int) -> String {
        let strs = "           机?=@#¥%&*字符串LHL这段时间研究了下弹幕的原理,并用swift实现了下.以此来记录.实现效果如下"
        var ranStr = ""
        for _ in 0..<len {
            ranStr.append(strs[strs.index(strs.startIndex, offsetBy: Int.random(in: 0..<strs.count))])
        }
        return ranStr
    }
}

var _vc: UIViewController!

let winBounds = UIScreen.main.bounds
let winSize = winBounds.size
let winW  = winSize.width
let winH = winSize.height
由于公司项目开始转为swift版本,ProgressHUD目前网上也没有很好的swift版本,自己模仿OC的toast写的一个swift版本。可以使用CocoaPods集成在项目中,使用非常简单方便。如有问题的地方还请各位大神多多指点。如果对你有用,可以star下,谢谢! swift版本指示器,基本所有项目中都会用到的。功能和OC版本的toast、MBProgressHUD基本相同、 CocoaPods CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command: $ gem install cocoapods To integrate XLProgressHUD 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 '' do pod 'XLProgressHUD', '~> 1.0.5' end Then, run the following command: $ pod install Usage Introduce import XLProgressHUD Use Code 1、单独内容信息提示 let message = "修改成功" view.showMessage(message, interval: 0.2, position: "top") 2、内容信息 + 图片 提示 let message = "修改成功" view.showMessageAndImage(message, image: UIImage(named: "true_icon"), interval: 0.2, position: "center") 3、标题信息 + 内容信息 + 图片 提示 let title = " 2" let message = "恭喜你!答对了" view.showTitleMessageAndImage(title, message: message, image: UIImage(named: "coins_big_icon"), interval: 0.2, position: "bottom") 4、网络请求持久显示提示 let message = "加载中..." view.showLoadingTilteActivity(message, position: "center") // 模拟网络数据加载设置的显示时间 let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))) dispatch_after(delayTime, dispatch_get_main_queue()) { () -> Void in // 隐藏提示视图 self.view.hideActivity() } Parameter description title: 显示提示框上部的文字参数 message: 显示提示下部的文字提示框 image: 显示提示框里面的图片参数 interval: 显示提示框显示时间的参数 position: 显示提示框显示位置 使用填入参数为("top" "center" "bottom") 默认为nil时现在在中部位置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值