美文网首页
导航栏或状态栏上的通知

导航栏或状态栏上的通知

作者: FlowYourHeart | 来源:发表于2018-07-26 15:47 被阅读26次

    话不多说

    效果图
    一行代码完成调用
    //                UNoticeBar(config: UNoticeBarConfig(title: "绿壳蛋鸡佛问发")).show(duration: 3)
                    UNoticeBar(config: UNoticeBarConfig(title: "佛说:要化了", image: UIImage.init(named: "mine_accout"), textColor: .white, backgroundColor: .black, barStyle: .onNavigationBar, animationType: UNoticeBarAnimationType.bottom)).show(duration: 3)
    

    代码片:

    //  UNoticeBar.swift
    import UIKit
    
    public enum UNoticeBarStyle {
        case onStatusBar
        case onNavigationBar
    }
    
    public enum UNoticeBarAnimationType {
        case top
        case bottom
        case left
        case right
    }
    
    extension UNoticeBarAnimationType {
        fileprivate func noticeBarViewTransform(with frame:CGRect, _ style:UNoticeBarStyle) -> CGAffineTransform {
            var transform = CGAffineTransform.identity
            
            switch (style, self) {
            case (_, .top):
                transform = CGAffineTransform(translationX: 0, y: -frame.height)
            case (_, .bottom):
                transform = CGAffineTransform(translationX: 0, y: -frame.height)
            case (_, .left):
                transform = CGAffineTransform(translationX: -frame.width, y: 0)
            case (_, .right):
                transform = CGAffineTransform(translationX: frame.width, y: 0)
        
            }
            return transform
            
        }
    }
    
    extension UNoticeBarStyle {
        fileprivate func noticeBarProperties() -> UNoticeBarProperties {
            let screenWidth = UIScreen.main.bounds.width
            
            var properties: UNoticeBarProperties
            switch self {
            case .onNavigationBar:
                properties = UNoticeBarProperties(shadowOffsetY: 3, fontSizeScaleFactor: 0.55, textFont: UIFont.systemFont(ofSize: 18), viewFrame: CGRect(origin: CGPoint.zero, size: CGSize(width: screenWidth, height: 44.0 + UIApplication.shared.statusBarFrame.height)))
            case .onStatusBar:
                properties = UNoticeBarProperties(shadowOffsetY: 2, fontSizeScaleFactor: 0.75, textFont: UIFont.systemFont(ofSize: 13), viewFrame: CGRect(origin: CGPoint.zero, size: CGSize(width: screenWidth, height: UIApplication.shared.statusBarFrame.height)))
            }
            return properties
        }
        
        fileprivate func noticeBarOriginY(superViewHeight: CGFloat, _ height: CGFloat) -> CGFloat {
            var originY: CGFloat = 0
            switch self {
            case .onNavigationBar:
                originY = UIApplication.shared.statusBarFrame.height + (superViewHeight - UIApplication.shared.statusBarFrame.height - height) * 0.5
            case .onStatusBar:
                originY = (superViewHeight - height) * 0.5
            }
            return originY
        }
        
        fileprivate var beginWindowLevel: UIWindowLevel {
            switch self {
            case .onStatusBar:
                return UIWindowLevelStatusBar + 1
            default:
                return UIWindowLevelNormal
            }
        }
        
        fileprivate var endWindowLevel: UIWindowLevel {
            return UIWindowLevelNormal
        }
    }
    
    fileprivate struct UNoticeBarProperties {
        init() {
            
        }
        var shadowOffsetY: CGFloat = 0
        var fontSizeScaleFactor: CGFloat = 0
        var textFont = UIFont()
        var viewFrame = CGRect.zero
        
        init(shadowOffsetY: CGFloat, fontSizeScaleFactor: CGFloat, textFont: UIFont, viewFrame: CGRect) {
            self.shadowOffsetY = shadowOffsetY
            self.fontSizeScaleFactor = fontSizeScaleFactor
            self.textFont = textFont
            self.viewFrame = viewFrame
        }
    }
    public struct UNoticeBarConfig {
        public init() { }
        public var title: String?
        public var image: UIImage? = nil
        public var margin: CGFloat = 10.0
        public var textColor: UIColor = UIColor.black
        public var backgroundColor = UIColor.white
        public var animationType = UNoticeBarAnimationType.top
        public var barStyle = UNoticeBarStyle.onNavigationBar
        
        public init(title: String? = nil,
                    image: UIImage? = nil,
                    textColor: UIColor = UIColor.white,
                    backgroundColor: UIColor = UIColor.orange,
                    barStyle: UNoticeBarStyle = .onNavigationBar,
                    animationType: UNoticeBarAnimationType = .top) {
            self.title = title
            self.image = image
            self.textColor = textColor
            self.backgroundColor = backgroundColor
            self.barStyle = barStyle
            self.animationType = animationType
        }
    }
    
    open class UNoticeBar: UIView {
        
        private var config = UNoticeBarConfig()
        
        private var _titleLabel: UILabel?
        private var _imageView: UIImageView?
        
        open var titleLabel: UILabel? {
            return _titleLabel
        }
        open var imageView: UIImageView? {
            return _imageView
        }
        
        public func show(duration: TimeInterval,completed: ((_ finished:Bool) -> Void)? = nil) {
            self.show(duration: duration, willShow: {
                [weak self] in
                guard let strongSelf = self else { return }
                let currentWindowLevel = strongSelf.config.barStyle.beginWindowLevel
                UIApplication.shared.keyWindow?.windowLevel = currentWindowLevel
            }, completed: {
                [weak self] (finished) in
                guard let strongSelf = self else {return}
                completed?(finished)
                if finished {
                    let currentWindowLevel = strongSelf.config.barStyle.endWindowLevel
                    UIApplication.shared.keyWindow?.windowLevel = currentWindowLevel
                }
            })
        }
        
        public init(config: UNoticeBarConfig) {
         super.init(frame: config.barStyle.noticeBarProperties().viewFrame)
            self.backgroundColor = config.backgroundColor
            self.config = config
            self.layer.shadowOffset = CGSize(width: 0, height: config.barStyle.noticeBarProperties().shadowOffsetY)
            self.layer.shadowColor = UIColor.lightGray.cgColor
            self.layer.shadowRadius = 5
            self.layer.shadowOpacity = 0.44
            configSubviews()
            
        }
        
        private override init(frame: CGRect) {
            super.init(frame: frame)
        }
        
        public required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        private func configSubviews() {
          _titleLabel = UILabel()
            _titleLabel?.text = config.title
            _titleLabel?.textColor = config.textColor
            _titleLabel?.minimumScaleFactor = config.barStyle.noticeBarProperties().fontSizeScaleFactor
            _titleLabel?.adjustsFontSizeToFitWidth = true
            _titleLabel?.font = config.barStyle.noticeBarProperties().textFont
            addSubview(_titleLabel!)
            
            var titleLabelOriginY: CGFloat = 0
            var titleLabelOriginX: CGFloat = 0
            var titleLabelSizeWidth: CGFloat = 0
            var titleLabelSizeHeight: CGFloat = 0
            
            if let image = config.image, config.barStyle != .onStatusBar {
                _imageView = UIImageView(image: image)
                _imageView?.contentMode = .scaleAspectFill
                addSubview(_imageView!)
                
                let imageViewWidth:CGFloat = 25
                let imageViewOriginX = config.margin + 10
                let imageViewOriginY = config.barStyle.noticeBarOriginY(superViewHeight: frame.height, imageViewWidth)
                _imageView?.frame = CGRect(origin: CGPoint(x: imageViewOriginX, y: imageViewOriginY), size: CGSize(width: imageViewWidth, height: imageViewWidth))
                
                
                titleLabelOriginX = _imageView!.frame.maxX + config.margin
                titleLabelOriginY = _imageView!.frame.origin.y
                titleLabelSizeHeight = _imageView!.frame.size.height
                titleLabelSizeWidth = UIScreen.main.bounds.width - titleLabelOriginX - config.margin
                _titleLabel?.textAlignment = .left
            } else {
                _titleLabel?.textAlignment = .center
                titleLabelSizeHeight = 25
                titleLabelSizeWidth = UIScreen.main.bounds.width - 2 * config.margin
                titleLabelOriginX = config.margin
                titleLabelOriginY = config.barStyle.noticeBarOriginY(superViewHeight:frame.height, titleLabelSizeHeight)
            }
            _titleLabel?.frame = CGRect(x: titleLabelOriginX, y: titleLabelOriginY, width: titleLabelSizeWidth, height: titleLabelSizeHeight)
        }
        
        private func show(duration: TimeInterval,willShow:() -> Void, completed: ((_ finished: Bool) -> Void)?) {
            if let subViews = UIApplication.shared.keyWindow?.subviews {
                for view in subViews {
                    if view.isKind(of: UNoticeBar.self) {
                        view.removeFromSuperview()
                    }
                }
            }
            willShow()
            
            UIApplication.shared.keyWindow?.addSubview(self)
            self.transform = config.animationType.noticeBarViewTransform(with: frame, self.config.barStyle)
            
            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {
                self.transform = CGAffineTransform.identity
            }) { (_) in
                DispatchQueue.main.asyncAfter(deadline: .now() + duration, execute: {
                    UIView.animate(withDuration: 0.4, animations: {
                        self.transform = self.config.animationType.noticeBarViewTransform(with: self.frame, self.config.barStyle)
                    }, completion: { (_) in
                        self.removeFromSuperview()
                    })
                })
            }
            
        }
        
        
        
    }
    
    

    相关文章

      网友评论

          本文标题:导航栏或状态栏上的通知

          本文链接:https://www.haomeiwen.com/subject/vvubmftx.html