`

swift -> Toast 效果

 
阅读更多

---------- 方案一 ------------------

 

https://github.com/xglofter/MyIOSCodes/tree/master/TGCToastView

 

由于 swift 版本更新 ,附上 新版本

//
//  ToastView.swift
//
//  Created by xglofter.
//  Copyright © 2016年 guang xu. All rights reserved.
//
import UIKit


let TGCToastHorizontalMargin: CGFloat = 12
let TGCToastVerticalMargin: CGFloat = 20
let TGCToastHorizontalMaxPer: CGFloat = 0.4  // 40% parent view width
let TGCToastVerticalMaxPer: CGFloat = 0.5    // 50% parent view height
let TGCToastImageWidth: CGFloat = 30
let TGCToastImageHeight: CGFloat = 30
let TGCToastSpaceBetweenTextAndImage: CGFloat = 14
let TGCToastErrorHeight: CGFloat = 25
let TGCToastErrorHorizontalMargin: CGFloat = 10
let TGCToastErrorVerticalMagin: CGFloat = 5

let TGCToastLayerCornerRadius: CGFloat = 12
let TGCToastLayerColor: UIColor = UIColor.black
let TGCToastLayerUseShadow: Bool = true
let TGCToastLayerShadowOpacity: CGFloat = 0.8
let TGCToastLayerShadowRadius: CGFloat = 5.0
let TGCToastLayerShadowOffset: CGSize = CGSize(width:3.0, height:3.0)
let TGCToastErrorLayerColor: UIColor = UIColor(red: 244/255, green: 81/255, blue: 78/255, alpha: 1)

let TGCToastTextColor: UIColor = UIColor.white
let TGCToastErrorTextColor: UIColor = UIColor.white

let TGCToastFadeInTime: Double = 0.5
let TGCToastFadeOutTime: Double = 0.4
let TGCToastDefaultTime: Double = 3
let TGCToastErrorMoveInTime: Double = 0.3
let TGCToastErrorMoveOutTime: Double = 0.2

var TGCTimer: UnsafePointer<Timer>? = nil
var TGCToastView: UnsafePointer<UIView>? = nil

var TGCErrorTimer: UnsafePointer<Timer>? = nil
var TGCErrorToastView: UnsafePointer<UIView>? = nil
var TGCErrorViewOriginBottomY: UnsafePointer<CGFloat>? = nil

extension UIView {
    
    /**
     make a toast (only text)
     - parameter message:  message text
     - parameter duration: toast showing time(default is 3 seconds)
     */
    func tgc_makeToast(message: String, duration: Double = TGCToastDefaultTime) {
        tgc_toMakeToast(message: message, duration: duration, image: nil)
    }
    
    /**
     make a toast (image with text)
     - parameter message:  message text
     - parameter image: image
     - parameter duration: toast showing time(default is 3 seconds)
     */
    func tgc_makeToast(message: String, image: UIImage, duration: Double = TGCToastDefaultTime) {
        tgc_toMakeToast(message: message, duration: duration, image: image)
    }
    
    /**
     make a toast (only image)
     - parameter image: image
     - parameter duration: toast showing time(default is 3 seconds)
     */
    func tgc_makeToastImage(image: UIImage, duration: Double = TGCToastDefaultTime) {
        tgc_toMakeToast(message: nil, duration: duration, image: image)
    }
    
    /**
     make a error toast view
     - parameter message:  error information
     - parameter duration: showing time(default is 3 seconds)
     */
    func tgc_makeErrorToast(message: String, originBottomPosY posY: CGFloat = 0, duration: Double = TGCToastDefaultTime) {
        
        objc_setAssociatedObject(self, &TGCErrorViewOriginBottomY, posY, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        if let errorView = objc_getAssociatedObject(self, &TGCErrorToastView) {
            if let timer = objc_getAssociatedObject(errorView, &TGCErrorTimer) {
                (timer as AnyObject).invalidate()
            }
            tgc_hideErrorView(view: errorView as! UIView, force: true)
        }
        
        let toast = tgc_errorView(message: message)
        self.addSubview(toast)
        objc_setAssociatedObject(self, &TGCErrorToastView, toast, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        tgc_showErrorView(view: toast, duration: duration)
    }
    
    private func tgc_toMakeToast(message: String?, duration: Double, image: UIImage?) {
        
        if let toastView = objc_getAssociatedObject(self, &TGCToastView) {
            if let timer = objc_getAssociatedObject(toastView, &TGCTimer) {
                (timer as AnyObject).invalidate()
            }
            tgc_hideWrapperView(view: toastView as! UIView, force: true)
        }
        
        let toast = tgc_wrapperView(msg: message, image: image)
        self.addSubview(toast)
        objc_setAssociatedObject(self, &TGCToastView, toast, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        tgc_showWrapperView(view: toast, duration: duration)
    }
    
    private func tgc_wrapperView(msg: String?, image: UIImage?) -> UIView {
        
        let wrapperView = UIView()
        wrapperView.layer.cornerRadius = TGCToastLayerCornerRadius
        wrapperView.backgroundColor = TGCToastLayerColor.withAlphaComponent(0.9)
        wrapperView.alpha = 0.0
        if TGCToastLayerUseShadow {
            wrapperView.layer.shadowColor = TGCToastLayerColor.cgColor
            wrapperView.layer.shadowOpacity = Float(TGCToastLayerShadowOpacity)
            wrapperView.layer.shadowRadius = TGCToastLayerShadowRadius
            wrapperView.layer.shadowOffset = TGCToastLayerShadowOffset
        }
        
        var imageView: UIImageView!
        var msgLabel: UILabel!
        let parentSize = self.bounds.size
        
        if image != nil {
            imageView = UIImageView(image: image)
            imageView.contentMode = .scaleAspectFill
            imageView.frame.size = CGSize(width:TGCToastImageWidth, height:TGCToastImageHeight)
            wrapperView.addSubview(imageView)
        }
        
        if msg != nil {
            msgLabel = UILabel()
            msgLabel.text = msg
            msgLabel.textColor = TGCToastTextColor
            msgLabel.font = UIFont.systemFont(ofSize: 14)
            msgLabel.lineBreakMode = .byWordWrapping
            msgLabel.numberOfLines = 0
            msgLabel.textAlignment = .center
            wrapperView.addSubview(msgLabel)
            
            let maxMsgWidth = parentSize.width * TGCToastHorizontalMaxPer - TGCToastHorizontalMargin * 2
            let maxMsgHeight = tgc_heightForLabel(textLabel: msgLabel, width: maxMsgWidth)
            msgLabel.frame.size = CGSize(width:maxMsgWidth, height:maxMsgHeight)
        }
        
        let imageHeight = (imageView != nil) ? imageView.frame.size.height + ((msgLabel != nil) ? TGCToastSpaceBetweenTextAndImage : 0) : 0
        let textHeight = (msgLabel != nil) ? msgLabel.frame.size.height : 0
        let wrapperWidth = parentSize.width * TGCToastHorizontalMaxPer
        let wrapperHeight = min(imageHeight + textHeight + TGCToastVerticalMargin * 2, parentSize.height * TGCToastVerticalMaxPer)
        wrapperView.frame.size = CGSize(width:wrapperWidth, height:wrapperHeight)
        wrapperView.center = CGPoint(x: parentSize.width * 0.5, y: parentSize.height * 0.5)
        
        if imageView != nil {
            imageView!.center = CGPoint(x:wrapperWidth * 0.5, y:TGCToastVerticalMargin + imageView!.frame.size.height * 0.5)
        }
        
        if msgLabel != nil {
            msgLabel!.center = CGPoint(x:wrapperWidth * 0.5, y:wrapperHeight - msgLabel!.frame.size.height * 0.5 - TGCToastVerticalMargin)
        }
        
        return wrapperView
    }
    
    private func tgc_errorView(message: String) -> UIView {
        
        let errorView = UIView()
        errorView.backgroundColor = TGCToastErrorLayerColor
        
        let textLabel = UILabel()
        textLabel.text = message
        textLabel.lineBreakMode = .byWordWrapping
        textLabel.numberOfLines = 0
        textLabel.textAlignment = .center
        textLabel.font = UIFont.systemFont(ofSize: 14)
        textLabel.textColor = TGCToastErrorTextColor
        errorView.addSubview(textLabel)
        
        let parentSize = self.bounds.size
        let maxTextWidth = parentSize.width - TGCToastErrorHorizontalMargin * 2
        let maxTextHeight = tgc_heightForLabel(textLabel: textLabel, width: maxTextWidth)
        textLabel.frame.size = CGSize(width:maxTextWidth, height:maxTextHeight)
        errorView.frame.size = CGSize(width:parentSize.width, height:maxTextHeight+TGCToastErrorVerticalMagin*2)
        textLabel.center = CGPoint(x:errorView.frame.size.width * 0.5, y:errorView.frame.size.height * 0.5)
        
        let posY = objc_getAssociatedObject(self, &TGCErrorViewOriginBottomY) as! CGFloat
        errorView.center = CGPoint(x:parentSize.width * 0.5, y:posY - errorView.frame.size.height * 0.5)
        
        return errorView
    }
    
    private func tgc_hideWrapperView(view: UIView, force: Bool) {
        func clearProperty() {
            view.removeFromSuperview()
            objc_setAssociatedObject(self, &TGCToastView, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            objc_setAssociatedObject(self, &TGCTimer, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        if force {
            clearProperty()
        } else {
            UIView.animate(withDuration: TGCToastFadeOutTime, delay: 0.0, options: [.curveEaseIn], animations: { view.alpha = 0.0 }) { (over: Bool) in
                clearProperty()
            }
        }
    }
    
    private func tgc_showWrapperView(view: UIView, duration: Double) {
        UIView.animate(withDuration: TGCToastFadeInTime, delay: 0, options: [.curveEaseOut], animations: { view.alpha = 1.0 }) { (over: Bool) in
            let timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(self.tgc_onToHideToastView), userInfo: view, repeats: false)
            objc_setAssociatedObject(view, &TGCTimer, timer, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    private func tgc_hideErrorView(view: UIView, force: Bool) {
        func clearProperty() {
            view.removeFromSuperview()
            objc_setAssociatedObject(self, &TGCErrorToastView, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            objc_setAssociatedObject(self, &TGCErrorTimer, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        if force {
            clearProperty()
        } else {
            UIView.animate(withDuration: TGCToastErrorMoveOutTime, delay: 0.0, options: [.curveEaseIn], animations: {
                let posY = objc_getAssociatedObject(self, &TGCErrorViewOriginBottomY) as! CGFloat
                view.frame.origin.y = posY - view.frame.size.height
            }) { (over: Bool) in
                clearProperty()
            }
        }
    }
    
    private func tgc_showErrorView(view: UIView, duration: Double) {
        UIView.animate(withDuration: TGCToastErrorMoveInTime, delay: 0, options: [.curveEaseOut], animations: {
            view.frame.origin.y += view.frame.size.height
        }) { (over: Bool) in
            let timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(self.tgc_onToHideErrorToastView), userInfo: view, repeats: false)
            objc_setAssociatedObject(view, &TGCErrorTimer, timer, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    func tgc_onToHideToastView(timer: Timer) {
        self.tgc_hideWrapperView(view: timer.userInfo as! UIView, force: false)
    }
    
    func tgc_onToHideErrorToastView(timer: Timer) {
        self.tgc_hideErrorView(view: timer.userInfo as! UIView, force: false)
    }
    
    /**
     get a UILabel's max height, with UILabel's width
     - parameter textLabel: the text label
     - parameter width:     the text label's width
     - returns: get the label max height
     */
    func tgc_heightForLabel(textLabel: UILabel, width: CGFloat) -> CGFloat {
        let attributes = [NSFontAttributeName: textLabel.font!]
        let rect = (textLabel.text! as NSString).boundingRect(with: CGSize(width:width, height:0), options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
        return rect.height
    }
}

  

 

--------- 方案二 ----------

参考: https://github.com/Rannie/Toast-Swift

 

 1 :     UIView.hr_setToastThemeColor(color: UIColor.blueColor());

 

        view.makeToast(message: "s是的发送到");


 

2:  self.view.makeToastActivity();



 

消失使用 self.view.hideToastActivity();

 

var timer: NSTimer!;

 

timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: #selector(self.timerAction), userInfo: nil, repeats: false);//第一次参数1表示重复执行间隔秒,初始化定时,timerAction=要执行的函数

 

    func timerAction(){

        print("do hide");

        self.view.hideToastActivity();

 

    }

 

3: self.view.makeToastActivityWithMessage(message: "加载中..");



 

消失 使用 2 里面的消失方法

 

 

HRToast+UIView.swift:

 

//
//  HRToast + UIView.swift
//  ToastDemo
//
//  Created by Rannie on 14/7/6.
//  Copyright (c) 2014年 Rannie. All rights reserved.
//  https://github.com/Rannie/Toast-Swift
//

import UIKit

/*
*  Infix overload method
*/
func /(lhs: CGFloat, rhs: Int) -> CGFloat {
    return lhs / CGFloat(rhs)
}

/*
*  Toast Config
*/
let HRToastDefaultDuration  =   2.0
let HRToastFadeDuration     =   0.2
let HRToastHorizontalMargin : CGFloat  =   10.0
let HRToastVerticalMargin   : CGFloat  =   10.0

let HRToastPositionDefault  =   "bottom"
let HRToastPositionTop      =   "top"
let HRToastPositionCenter   =   "center"

// activity
let HRToastActivityWidth  :  CGFloat  = 100.0
let HRToastActivityHeight :  CGFloat  = 100.0
let HRToastActivityPositionDefault    = "center"

// image size
let HRToastImageViewWidth :  CGFloat  = 80.0
let HRToastImageViewHeight:  CGFloat  = 80.0

// label setting
let HRToastMaxWidth       :  CGFloat  = 0.8;      // 80% of parent view width
let HRToastMaxHeight      :  CGFloat  = 0.8;
let HRToastFontSize       :  CGFloat  = 16.0
let HRToastMaxTitleLines              = 0
let HRToastMaxMessageLines            = 0

// shadow appearance
let HRToastShadowOpacity  : CGFloat   = 0.8
let HRToastShadowRadius   : CGFloat   = 6.0
let HRToastShadowOffset   : CGSize    = CGSizeMake(CGFloat(4.0), CGFloat(4.0))

let HRToastOpacity        : CGFloat   = 0.9
let HRToastCornerRadius   : CGFloat   = 10.0

var HRToastActivityView: UnsafePointer<UIView>    =   nil
var HRToastTimer: UnsafePointer<NSTimer>          =   nil
var HRToastView: UnsafePointer<UIView>            =   nil
var HRToastThemeColor : UnsafePointer<UIColor>    =   nil
var HRToastTitleFontName: UnsafePointer<String>   =   nil
var HRToastFontName: UnsafePointer<String>        =   nil
var HRToastFontColor: UnsafePointer<UIColor>      =   nil

/*
*  Custom Config
*/
let HRToastHidesOnTap       =   true
let HRToastDisplayShadow    =   true

//HRToast (UIView + Toast using Swift)

extension UIView {
    
    /*
    *  public methods
    */
    class func hr_setToastThemeColor(color color: UIColor) {
        objc_setAssociatedObject(self, &HRToastThemeColor, color, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
    
    class func hr_toastThemeColor() -> UIColor {
        var color = objc_getAssociatedObject(self, &HRToastThemeColor) as! UIColor?
        if color == nil {
            color = UIColor.blackColor()
            UIView.hr_setToastThemeColor(color: color!)
        }
        return color!
    }
    
    class func hr_setToastTitleFontName(fontName fontName: String) {
        objc_setAssociatedObject(self, &HRToastTitleFontName, fontName, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
    
    class func hr_toastTitleFontName() -> String {
        var name = objc_getAssociatedObject(self, &HRToastTitleFontName) as! String?
        if name == nil {
            let font = UIFont.systemFontOfSize(12.0)
            name = font.fontName
            UIView.hr_setToastTitleFontName(fontName: name!)
        }
        
        return name!
    }
    
    class func hr_setToastFontName(fontName fontName: String) {
        objc_setAssociatedObject(self, &HRToastFontName, fontName, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
    
    class func hr_toastFontName() -> String {
        var name = objc_getAssociatedObject(self, &HRToastFontName) as! String?
        if name == nil {
            let font = UIFont.systemFontOfSize(12.0)
            name = font.fontName
            UIView.hr_setToastFontName(fontName: name!)
        }
        
        return name!
    }
    
    class func hr_setToastFontColor(color color: UIColor) {
        objc_setAssociatedObject(self, &HRToastFontColor, color, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
    
    class func hr_toastFontColor() -> UIColor {
        var color = objc_getAssociatedObject(self, &HRToastFontColor) as! UIColor?
        if color == nil {
            color = UIColor.whiteColor()
            UIView.hr_setToastFontColor(color: color!)
        }
        
        return color!
    }
    
    func makeToastActivityWithMessage(message msg: String){
        self.makeToastActivity(position: HRToastActivityPositionDefault, message: msg)
    }
    
    func makeToast(message msg: String) {
        self.makeToast(message: msg, duration: HRToastDefaultDuration, position: HRToastPositionDefault)
    }
    
    func makeToast(message msg: String, duration: Double, position: AnyObject) {
        let toast = self.viewForMessage(msg, title: nil, image: nil)
        self.showToast(toast: toast!, duration: duration, position: position)
    }
    
    func makeToast(message msg: String, duration: Double, position: AnyObject, title: String) {
        let toast = self.viewForMessage(msg, title: title, image: nil)
        self.showToast(toast: toast!, duration: duration, position: position)
    }
    
    func makeToast(message msg: String, duration: Double, position: AnyObject, image: UIImage) {
        let toast = self.viewForMessage(msg, title: nil, image: image)
        self.showToast(toast: toast!, duration: duration, position: position)
    }
    
    func makeToast(message msg: String, duration: Double, position: AnyObject, title: String, image: UIImage) {
        let toast = self.viewForMessage(msg, title: title, image: image)
        self.showToast(toast: toast!, duration: duration, position: position)
    }
    
    func showToast(toast toast: UIView) {
        self.showToast(toast: toast, duration: HRToastDefaultDuration, position: HRToastPositionDefault)
    }
    
    private func showToast(toast toast: UIView, duration: Double, position: AnyObject) {
        let existToast = objc_getAssociatedObject(self, &HRToastView) as! UIView?
        if existToast != nil {
            if let timer: NSTimer = objc_getAssociatedObject(existToast, &HRToastTimer) as? NSTimer {
                timer.invalidate();
            }
            self.hideToast(toast: existToast!, force: false);
        }
        
        toast.center = self.centerPointForPosition(position, toast: toast)
        toast.alpha = 0.0
        
        if HRToastHidesOnTap {
            let tapRecognizer = UITapGestureRecognizer(target: toast, action: #selector(UIView.handleToastTapped(_:)))
            toast.addGestureRecognizer(tapRecognizer)
            toast.userInteractionEnabled = true;
            toast.exclusiveTouch = true;
        }
        
        self.addSubview(toast)
        objc_setAssociatedObject(self, &HRToastView, toast, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        
        UIView.animateWithDuration(HRToastFadeDuration,
            delay: 0.0, options: ([.CurveEaseOut, .AllowUserInteraction]),
            animations: {
                toast.alpha = 1.0
            },
            completion: { (finished: Bool) in
                let timer = NSTimer.scheduledTimerWithTimeInterval(duration, target: self, selector: #selector(UIView.toastTimerDidFinish(_:)), userInfo: toast, repeats: false)
                objc_setAssociatedObject(toast, &HRToastTimer, timer, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        })
    }
    
    func makeToastActivity() {
        self.makeToastActivity(position: HRToastActivityPositionDefault)
    }
    
    func makeToastActivity(message msg: String){
        self.makeToastActivity(position: HRToastActivityPositionDefault, message: msg)
    }
    
    private func makeToastActivity(position pos: AnyObject, message msg: String = "") {
        let existingActivityView: UIView? = objc_getAssociatedObject(self, &HRToastActivityView) as? UIView
        if existingActivityView != nil { return }
        
        let activityView = UIView(frame: CGRectMake(0, 0, HRToastActivityWidth, HRToastActivityHeight))
        activityView.center = self.centerPointForPosition(pos, toast: activityView)
        activityView.backgroundColor = UIView.hr_toastThemeColor().colorWithAlphaComponent(HRToastOpacity)
        activityView.alpha = 0.0
        activityView.autoresizingMask = ([.FlexibleLeftMargin, .FlexibleTopMargin, .FlexibleRightMargin, .FlexibleBottomMargin])
        activityView.layer.cornerRadius = HRToastCornerRadius
        
        if HRToastDisplayShadow {
            activityView.layer.shadowColor = UIView.hr_toastThemeColor().CGColor
            activityView.layer.shadowOpacity = Float(HRToastShadowOpacity)
            activityView.layer.shadowRadius = HRToastShadowRadius
            activityView.layer.shadowOffset = HRToastShadowOffset
        }
        
        let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
        activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2)
        activityView.addSubview(activityIndicatorView)
        activityIndicatorView.startAnimating()
        
        if (!msg.isEmpty){
            activityIndicatorView.frame.origin.y -= 10
            let activityMessageLabel = UILabel(frame: CGRectMake(activityView.bounds.origin.x, (activityIndicatorView.frame.origin.y + activityIndicatorView.frame.size.height + 10), activityView.bounds.size.width, 20))
            activityMessageLabel.textColor = UIView.hr_toastFontColor()
            activityMessageLabel.font = (msg.characters.count<=10) ? UIFont(name:UIView.hr_toastFontName(), size: 16) : UIFont(name:UIView.hr_toastFontName(), size: 13)
            activityMessageLabel.textAlignment = .Center
            activityMessageLabel.text = msg
            activityView.addSubview(activityMessageLabel)
        }
        
        self.addSubview(activityView)
        
        // associate activity view with self
        objc_setAssociatedObject(self, &HRToastActivityView, activityView, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
        UIView.animateWithDuration(HRToastFadeDuration,
            delay: 0.0,
            options: UIViewAnimationOptions.CurveEaseOut,
            animations: {
                activityView.alpha = 1.0
            },
            completion: nil)
    }
    
    func hideToastActivity() {
        let existingActivityView = objc_getAssociatedObject(self, &HRToastActivityView) as! UIView?
        if existingActivityView == nil { return }
        UIView.animateWithDuration(HRToastFadeDuration,
            delay: 0.0,
            options: UIViewAnimationOptions.CurveEaseOut,
            animations: {
                existingActivityView!.alpha = 0.0
            },
            completion: { (finished: Bool) in
                existingActivityView!.removeFromSuperview()
                objc_setAssociatedObject(self, &HRToastActivityView, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        })
    }
    
    /*
    *  private methods (helper)
    */
    func hideToast(toast toast: UIView) {
        self.hideToast(toast: toast, force: false);
    }
    
    func hideToast(toast toast: UIView, force: Bool) {
        let completeClosure = { (finish: Bool) -> () in
            toast.removeFromSuperview()
            objc_setAssociatedObject(self, &HRToastTimer, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        
        if force {
            completeClosure(true)
        } else {
            UIView.animateWithDuration(HRToastFadeDuration,
                delay: 0.0,
                options: ([.CurveEaseIn, .BeginFromCurrentState]),
                animations: {
                    toast.alpha = 0.0
                },
                completion:completeClosure)
        }
    }
    
    func toastTimerDidFinish(timer: NSTimer) {
        self.hideToast(toast: timer.userInfo as! UIView)
    }
    
    func handleToastTapped(recognizer: UITapGestureRecognizer) {
        let timer = objc_getAssociatedObject(self, &HRToastTimer) as! NSTimer
        timer.invalidate()
        
        self.hideToast(toast: recognizer.view!)
    }
    
    private func centerPointForPosition(position: AnyObject, toast: UIView) -> CGPoint {
        if position is String {
            let toastSize = toast.bounds.size
            let viewSize  = self.bounds.size
            if position.lowercaseString == HRToastPositionTop {
                return CGPointMake(viewSize.width/2, toastSize.height/2 + HRToastVerticalMargin)
            } else if position.lowercaseString == HRToastPositionDefault {
                return CGPointMake(viewSize.width/2, viewSize.height - toastSize.height/2 - HRToastVerticalMargin)
            } else if position.lowercaseString == HRToastPositionCenter {
                return CGPointMake(viewSize.width/2, viewSize.height/2)
            }
        } else if position is NSValue {
            return position.CGPointValue
        }
        
        print("Warning: Invalid position for toast.")
        return self.centerPointForPosition(HRToastPositionDefault, toast: toast)
    }
    
    private func viewForMessage(msg: String?, title: String?, image: UIImage?) -> UIView? {
        if msg == nil && title == nil && image == nil { return nil }
        
        var msgLabel: UILabel?
        var titleLabel: UILabel?
        var imageView: UIImageView?
        
        let wrapperView = UIView()
        wrapperView.autoresizingMask = ([.FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin, .FlexibleBottomMargin])
        wrapperView.layer.cornerRadius = HRToastCornerRadius
        wrapperView.backgroundColor = UIView.hr_toastThemeColor().colorWithAlphaComponent(HRToastOpacity)
        
        if HRToastDisplayShadow {
            wrapperView.layer.shadowColor = UIView.hr_toastThemeColor().CGColor
            wrapperView.layer.shadowOpacity = Float(HRToastShadowOpacity)
            wrapperView.layer.shadowRadius = HRToastShadowRadius
            wrapperView.layer.shadowOffset = HRToastShadowOffset
        }
        
        if image != nil {
            imageView = UIImageView(image: image)
            imageView!.contentMode = .ScaleAspectFit
            imageView!.frame = CGRectMake(HRToastHorizontalMargin, HRToastVerticalMargin, CGFloat(HRToastImageViewWidth), CGFloat(HRToastImageViewHeight))
        }
        
        var imageWidth: CGFloat, imageHeight: CGFloat, imageLeft: CGFloat
        if imageView != nil {
            imageWidth = imageView!.bounds.size.width
            imageHeight = imageView!.bounds.size.height
            imageLeft = HRToastHorizontalMargin
        } else {
            imageWidth  = 0.0; imageHeight = 0.0; imageLeft   = 0.0
        }
        
        if title != nil {
            titleLabel = UILabel()
            titleLabel!.numberOfLines = HRToastMaxTitleLines
            titleLabel!.font = UIFont(name: UIView.hr_toastFontName(), size: HRToastFontSize)
            titleLabel!.textAlignment = .Center
            titleLabel!.lineBreakMode = .ByWordWrapping
            titleLabel!.textColor = UIView.hr_toastFontColor()
            titleLabel!.backgroundColor = UIColor.clearColor()
            titleLabel!.alpha = 1.0
            titleLabel!.text = title
            
            // size the title label according to the length of the text
            let maxSizeTitle = CGSizeMake((self.bounds.size.width * HRToastMaxWidth) - imageWidth, self.bounds.size.height * HRToastMaxHeight);
            let expectedHeight = title!.stringHeightWithFontSize(HRToastFontSize, width: maxSizeTitle.width)
            titleLabel!.frame = CGRectMake(0.0, 0.0, maxSizeTitle.width, expectedHeight)
        }
        
        if msg != nil {
            msgLabel = UILabel();
            msgLabel!.numberOfLines = HRToastMaxMessageLines
            msgLabel!.font = UIFont(name: UIView.hr_toastFontName(), size: HRToastFontSize)
            msgLabel!.lineBreakMode = .ByWordWrapping
            msgLabel!.textAlignment = .Center
            msgLabel!.textColor = UIView.hr_toastFontColor()
            msgLabel!.backgroundColor = UIColor.clearColor()
            msgLabel!.alpha = 1.0
            msgLabel!.text = msg
            
            let maxSizeMessage = CGSizeMake((self.bounds.size.width * HRToastMaxWidth) - imageWidth, self.bounds.size.height * HRToastMaxHeight)
            let expectedHeight = msg!.stringHeightWithFontSize(HRToastFontSize, width: maxSizeMessage.width)
            msgLabel!.frame = CGRectMake(0.0, 0.0, maxSizeMessage.width, expectedHeight)
        }
        
        var titleWidth: CGFloat, titleHeight: CGFloat, titleTop: CGFloat, titleLeft: CGFloat
        if titleLabel != nil {
            titleWidth = titleLabel!.bounds.size.width
            titleHeight = titleLabel!.bounds.size.height
            titleTop = HRToastVerticalMargin
            titleLeft = imageLeft + imageWidth + HRToastHorizontalMargin
        } else {
            titleWidth = 0.0; titleHeight = 0.0; titleTop = 0.0; titleLeft = 0.0
        }
        
        var msgWidth: CGFloat, msgHeight: CGFloat, msgTop: CGFloat, msgLeft: CGFloat
        if msgLabel != nil {
            msgWidth = msgLabel!.bounds.size.width
            msgHeight = msgLabel!.bounds.size.height
            msgTop = titleTop + titleHeight + HRToastVerticalMargin
            msgLeft = imageLeft + imageWidth + HRToastHorizontalMargin
        } else {
            msgWidth = 0.0; msgHeight = 0.0; msgTop = 0.0; msgLeft = 0.0
        }
        
        let largerWidth = max(titleWidth, msgWidth)
        let largerLeft  = max(titleLeft, msgLeft)
        
        // set wrapper view's frame
        let wrapperWidth  = max(imageWidth + HRToastHorizontalMargin * 2, largerLeft + largerWidth + HRToastHorizontalMargin)
        let wrapperHeight = max(msgTop + msgHeight + HRToastVerticalMargin, imageHeight + HRToastVerticalMargin * 2)
        wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight)
        
        // add subviews
        if titleLabel != nil {
            titleLabel!.frame = CGRectMake(titleLeft, titleTop, titleWidth, titleHeight)
            wrapperView.addSubview(titleLabel!)
        }
        if msgLabel != nil {
            msgLabel!.frame = CGRectMake(msgLeft, msgTop, msgWidth, msgHeight)
            wrapperView.addSubview(msgLabel!)
        }
        if imageView != nil {
            wrapperView.addSubview(imageView!)
        }
        
        return wrapperView
    }
    
}

extension String {
    
    func stringHeightWithFontSize(fontSize: CGFloat,width: CGFloat) -> CGFloat {
        let font = UIFont(name: UIView.hr_toastFontName(), size: HRToastFontSize)
        let size = CGSizeMake(width, CGFloat.max)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .ByWordWrapping;
        let attributes = [NSFontAttributeName:font!,
            NSParagraphStyleAttributeName:paragraphStyle.copy()]
        
        let text = self as NSString
        let rect = text.boundingRectWithSize(size, options:.UsesLineFragmentOrigin, attributes: attributes, context:nil)
        return rect.size.height
    }
    
}

 

 

 

  • 大小: 14.4 KB
  • 大小: 11.8 KB
  • 大小: 11.7 KB
分享到:
评论

相关推荐

    swift-iOSToast提示框(Objective-C)

    本主题将深入探讨如何在Swift项目中使用Objective-C编写的`YTToast`库来实现Toast提示框。 首先,我们需要添加`YTToast`库到我们的Swift项目中。由于这个库是用Objective-C编写的,因此我们需要遵循Swift与...

    swift-AutoMessageDialog自定义toast提示封装

    `AutoMessageDialog`是一个专为Swift设计的自定义toast提示封装库,它允许开发者轻松地在应用中创建和显示个性化消息提示。下面将详细介绍这个库的使用方法、核心功能以及其在实际开发中的应用。 `...

    swift-CSToast-OC一个简单的提示框Toast.

    在iOS应用开发中,用户界面的交互体验是至关重要的,其中一种常见的用户提示方式就是“Toast”。Toast是一种轻量级的提示方式,它不会占据整个屏幕,而是短暂地出现在屏幕底部或中间,显示一些简短的信息,然后自动...

    swift等待效果+toast提示

    在iOS应用开发中,用户体验是至关重要的,而“swift等待效果+toast提示”就是提升用户体验的一种常见技术。Swift等待效果通常指的是在进行网络请求或其他耗时操作时显示一个加载指示器,让用户知道应用正在忙碌,...

    swiftui-ios-toast-notification

    func makeUIView(context: Context) -&gt; UIView { let view = UIView() let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert) let action = UIAlertAction(title: ...

    ios-Toast.zip

    "ios-Toast.zip"这个压缩包很可能包含了一个实现iOS Toast效果的代码库或者示例项目。 在iOS中,虽然没有内置的Toast控件,但开发者可以通过自定义UIView或者使用第三方库来实现类似的功能。文件"UNToast"可能就是...

    Toast-Swift:快速查看吐司视图

    新的Toast-Swift可以使用Swift 3.0进行编译。 您可以设置烤面包视图的主题颜色。 安装 下载此仓库并导入“ UIView + HRToast”。 用法 设置主题颜色(默认为UIColor.blackColor()) view.hr_setToastThemeColor...

    IOS上类似android的TOAST弹出窗口

    总的来说,虽然iOS系统原生不提供Toast功能,但通过引入第三方库如`Toast-Swift`,开发者可以轻松实现与Android类似的快速提示效果,提高用户体验。在项目中合理使用这类库,可以使代码更简洁,同时保持界面的统一性...

    iOS 仿android 中的Toast实现

    private func animateHide(completion: (() -&gt; Void)? = nil) { // 添加动画效果,隐藏视图 completion?() } } ``` 在实际项目中,你可能还需要一个工具类来管理这些`ZHTOASTView`实例,例如`ZHTOASTManager`,...

    Swift 实现Loading

    本项目是关于"漂亮的Loading动画收集"的Swift版本实现,包含了多种风格和效果的加载指示器。 首先,"ActivityIndi"通常指的是`UIActivityIndicatorView`,它是iOS SDK中内置的一个用于显示活动指示器的类。这种控件...

    仿照安卓Toast 弹窗提示

    要实现类似Toast的自动消失效果,我们需要添加显示和消失的动画。这可以通过调用`UIView`的`animate(withDuration:animations:)`方法来实现。在显示动画中,将自定义视图添加到主窗口(`UIApplication.shared....

    iOS提示弹框

    你可以自定义弹框的背景颜色、文字颜色、边框宽度和颜色、动画效果等。例如,可以这样改变默认样式: ```swift alert.backgroundColor = UIColor.lightGray alert.titleColor = UIColor.black alert.messageColor =...

    iPhone上的Toast

    为了创建一个类似Toast的效果,开发者通常需要以下步骤: 1. **定义视图**:创建一个UIView子类,该子类将包含显示文字的UILabel和其他可选的UI元素,如背景颜色、边框等。 2. **设置文本**:根据需求设置文字内容...

    IOS Toast的使用

    在显示和消失时,可以使用动画效果。虽然自定义实现更灵活,但也会增加代码复杂性。 总的来说,实现iOS中的Toast功能并不复杂,主要涉及第三方库的选择与集成,以及可能的自定义需求。无论选择哪种方式,都要确保其...

    ios demo,toast view,可以指定在屏幕的中心显示或底部显示

    在压缩包的`test_toast`文件中,可能包含了这个demo的源代码,包括Xcode工程文件、Swift或Objective-C的实现文件、资源文件等。通过阅读和分析这些代码,你可以深入理解如何在实际项目中实现自定义的、可配置显示...

    toast notifications.zip

    "Toast Notifications.zip" 是一个开源项目,主要是一个Swift语言扩展,它为UIView对象类增加了吐司通知的功能。这个扩展使得开发者能够轻松地在iOS应用中实现类似Android系统中的"吐司"通知效果,即短暂显示一个小...

    iOS toast demo

    在Objective-C或Swift中实现Toast,开发者通常会创建一个UIView子类,设计其外观,然后通过添加和移除该视图到窗口(window)来实现显示和消失的效果。在"iOS toast demo"中,这个自定义视图可能包含了一个UILabel...

    iOS编写Android的Toast控件

    在iOS开发中,为了实现类似Android的Toast效果,开发者经常需要自定义一个控件来达到显示短暂消息的目的。本教程将深入讲解如何在iOS中创建一个功能与Android Toast相似的自定义控件,以帮助iOS应用增加更多元化的...

    一个易于上手又完全可定制化的专业HUD库(内含Toast、Alert、Sheet三件套).zip

    本资源提供了一个专业的HUD库,名为"ProHUD",它具有易用性和高度可定制性,支持Swift编程语言,并且包含了Toast、Alert和Sheet三种常见UI组件,适用于多种场景。 首先,让我们深入了解一下Toast、Alert和Sheet这三...

    IOS ToastKit

    **iOS ToastKit详解** 在iOS应用开发中,为了提供用户友好的交互体验,开发者常常需要在界面中短暂显示一些...通过简单地调用几个方法,你就可以轻松地在你的iOS应用中实现与Android相似的Toast效果,提升用户体验。

Global site tag (gtag.js) - Google Analytics