diff --git a/SweetAlert/SweetAlert.swift b/SweetAlert/SweetAlert.swift index 6c7b30a..ecd05a7 100644 --- a/SweetAlert/SweetAlert.swift +++ b/SweetAlert/SweetAlert.swift @@ -1,3 +1,4 @@ + // // SweetAlert.swift // SweetAlert @@ -5,7 +6,6 @@ // Created by Codester on 11/3/14. // Copyright (c) 2014 Codester. All rights reserved. // - import Foundation import UIKit import QuartzCore @@ -35,7 +35,7 @@ open class SweetAlert: UIViewController { var subTitleTextView = UITextView() var userAction:((_ isOtherButton: Bool) -> Void)? = nil let kFont = "Helvetica" - + init() { super.init(nibName: nil, bundle: nil) self.view.frame = UIScreen.main.bounds @@ -46,7 +46,7 @@ open class SweetAlert: UIViewController { //Retaining itself strongly so can exist without strong refrence strongSelf = self } - + required public init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -62,7 +62,7 @@ open class SweetAlert: UIViewController { contentView.layer.borderColor = UIColor.colorFromRGB(0xCCCCCC).cgColor view.addSubview(contentView) } - + fileprivate func setupTitleLabel() { titleLabel.text = "" titleLabel.numberOfLines = 1 @@ -87,7 +87,7 @@ open class SweetAlert: UIViewController { let width: CGFloat = kContentWidth - (kWidthMargin*2) if animatedView != nil { - animatedView!.frame = CGRect(x: (kContentWidth - kAnimatedViewHeight) / 2.0, y: y, width: kAnimatedViewHeight, height: kAnimatedViewHeight) + animatedView!.frame = CGRect(x: (kContentWidth - kAnimatedViewHeight) / 2.0, y: y, width: kAnimatedViewHeight, height: kAnimatedViewHeight) contentView.addSubview(animatedView!) y += kAnimatedViewHeight + kHeightMargin } @@ -97,7 +97,7 @@ open class SweetAlert: UIViewController { contentView.addSubview(imageView!) y += imageView!.frame.size.height + kHeightMargin } - + // Title if self.titleLabel.text != nil { titleLabel.frame = CGRect(x: x, y: y, width: width, height: kTitleHeight) @@ -108,7 +108,7 @@ open class SweetAlert: UIViewController { // Subtitle if self.subTitleTextView.text.isEmpty == false { let subtitleString = subTitleTextView.text! as NSString - let rect = subtitleString.boundingRect(with: CGSize(width: width, height: 0.0), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName:subTitleTextView.font!], context: nil) + let rect = subtitleString.boundingRect(with: CGSize(width: width, height: 0.0), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font:subTitleTextView.font!], context: nil) textViewHeight = ceil(rect.size.height) + 10.0 subTitleTextView.frame = CGRect(x: x, y: y, width: width, height: textViewHeight) contentView.addSubview(subTitleTextView) @@ -118,7 +118,7 @@ open class SweetAlert: UIViewController { var buttonRect:[CGRect] = [] for button in buttons { let string = button.title(for: UIControlState())! as NSString - buttonRect.append(string.boundingRect(with: CGSize(width: width, height:0.0), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:[NSFontAttributeName:button.titleLabel!.font], context:nil)) + buttonRect.append(string.boundingRect(with: CGSize(width: width, height:0.0), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes:[NSAttributedStringKey.font:button.titleLabel!.font], context:nil)) } var totalWidth: CGFloat = 0.0 @@ -132,35 +132,35 @@ open class SweetAlert: UIViewController { var buttonX = (kContentWidth - totalWidth ) / 2.0 for i in 0 ..< buttons.count { - buttons[i].frame = CGRect(x: buttonX, y: y, width: buttonRect[i].size.width + 20.0, height: buttonRect[i].size.height + 10.0) - buttonX = buttons[i].frame.origin.x + kWidthMargin + buttonRect[i].size.width + 20.0 - buttons[i].layer.cornerRadius = 5.0 - self.contentView.addSubview(buttons[i]) - buttons[i].addTarget(self, action: #selector(SweetAlert.pressed(_:)), for: UIControlEvents.touchUpInside) - + buttons[i].frame = CGRect(x: buttonX, y: y, width: buttonRect[i].size.width + 20.0, height: buttonRect[i].size.height + 10.0) + buttonX = buttons[i].frame.origin.x + kWidthMargin + buttonRect[i].size.width + 20.0 + buttons[i].layer.cornerRadius = 5.0 + self.contentView.addSubview(buttons[i]) + buttons[i].addTarget(self, action: #selector(SweetAlert.pressed(_:)), for: UIControlEvents.touchUpInside) + } y += kHeightMargin + buttonRect[0].size.height + 10.0 if y > kMaxHeight { let diff = y - kMaxHeight let sFrame = subTitleTextView.frame subTitleTextView.frame = CGRect(x: sFrame.origin.x, y: sFrame.origin.y, width: sFrame.width, height: sFrame.height - diff) - + for button in buttons { let bFrame = button.frame button.frame = CGRect(x: bFrame.origin.x, y: bFrame.origin.y - diff, width: bFrame.width, height: bFrame.height) } - + y = kMaxHeight } - + contentView.frame = CGRect(x: (mainScreenBounds.size.width - kContentWidth) / 2.0, y: (mainScreenBounds.size.height - y) / 2.0, width: kContentWidth, height: y) contentView.clipsToBounds = true } - open func pressed(_ sender: UIButton!) { + @objc open func pressed(_ sender: UIButton!) { self.closeAlert(sender.tag) } - + open override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() var sz = UIScreen.main.bounds.size @@ -175,7 +175,7 @@ open class SweetAlert: UIViewController { } self.resizeAndRelayout() } - + func closeAlert(_ buttonIndex:Int){ if userAction != nil { let isOtherButton = buttonIndex == 0 ? true: false @@ -183,7 +183,7 @@ open class SweetAlert: UIViewController { userAction!(isOtherButton) SweetAlertContext.shouldNotAnimate = false } - + UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseOut, animations: { () -> Void in self.view.alpha = 0.0 }) { (Bool) -> Void in @@ -194,9 +194,9 @@ open class SweetAlert: UIViewController { self.strongSelf = nil } } - - func cleanUpAlert() { + func cleanUpAlert() { + if self.animatedView != nil { self.animatedView!.removeFromSuperview() self.animatedView = nil @@ -213,9 +213,9 @@ open class SweetAlert: UIViewController { open func showAlert(_ title: String, subTitle: String?, style: AlertStyle) -> SweetAlert { _ = showAlert(title, subTitle: subTitle, style: style, buttonTitle: "OK") return self - + } - + open func showAlert(_ title: String, subTitle: String?, style: AlertStyle,buttonTitle: String, action: ((_ isOtherButton: Bool) -> Void)? = nil) -> SweetAlert { _ = showAlert(title, subTitle: subTitle, style: style, buttonTitle: buttonTitle,buttonColor: UIColor.colorFromRGB(0xAEDEF4)) userAction = action @@ -228,106 +228,106 @@ open class SweetAlert: UIViewController { userAction = action return self } - + open func showAlert(_ title: String, subTitle: String?, style: AlertStyle,buttonTitle: String,buttonColor: UIColor,otherButtonTitle: String?, action: ((_ isOtherButton: Bool) -> Void)? = nil) -> SweetAlert { - self.showAlert(title, subTitle: subTitle, style: style, buttonTitle: buttonTitle,buttonColor: buttonColor,otherButtonTitle: - otherButtonTitle,otherButtonColor: UIColor.red) - userAction = action - return self + self.showAlert(title, subTitle: subTitle, style: style, buttonTitle: buttonTitle,buttonColor: buttonColor,otherButtonTitle: + otherButtonTitle,otherButtonColor: UIColor.red) + userAction = action + return self } open func showAlert(_ title: String, subTitle: String?, style: AlertStyle,buttonTitle: String,buttonColor: UIColor,otherButtonTitle: String?, otherButtonColor: UIColor?,action: ((_ isOtherButton: Bool) -> Void)? = nil) { - userAction = action - let window: UIWindow = UIApplication.shared.keyWindow! - window.addSubview(view) - window.bringSubview(toFront: view) - view.frame = window.bounds - self.setupContentView() - self.setupTitleLabel() - self.setupSubtitleTextView() - - switch style { - case .success: - self.animatedView = SuccessAnimatedView() - - case .error: - self.animatedView = CancelAnimatedView() - - case .warning: - self.animatedView = InfoAnimatedView() - - case let .customImage(imageFile): - if let image = UIImage(named: imageFile) { - self.imageView = UIImageView(image: image) - } - case .none: - self.animatedView = nil - } - - self.titleLabel.text = title - if subTitle != nil { - self.subTitleTextView.text = subTitle - } - buttons = [] - if buttonTitle.isEmpty == false { - let button: UIButton = UIButton(type: UIButtonType.custom) - button.setTitle(buttonTitle, for: UIControlState()) - button.backgroundColor = buttonColor - button.isUserInteractionEnabled = true - button.tag = 0 - buttons.append(button) - } + userAction = action + let window: UIWindow = UIApplication.shared.keyWindow! + window.addSubview(view) + window.bringSubview(toFront: view) + view.frame = window.bounds + self.setupContentView() + self.setupTitleLabel() + self.setupSubtitleTextView() + + switch style { + case .success: + self.animatedView = SuccessAnimatedView() - if otherButtonTitle != nil && otherButtonTitle!.isEmpty == false { - let button: UIButton = UIButton(type: UIButtonType.custom) - button.setTitle(otherButtonTitle, for: UIControlState()) - button.backgroundColor = otherButtonColor - button.addTarget(self, action: #selector(SweetAlert.pressed(_:)), for: UIControlEvents.touchUpInside) - button.tag = 1 - buttons.append(button) - } - - resizeAndRelayout() - if SweetAlertContext.shouldNotAnimate == true { - //Do not animate Alert - if self.animatedView != nil { - self.animatedView!.animate() - } + case .error: + self.animatedView = CancelAnimatedView() + + case .warning: + self.animatedView = InfoAnimatedView() + + case let .customImage(imageFile): + if let image = UIImage(named: imageFile) { + self.imageView = UIImageView(image: image) } - else { - animateAlert() + case .none: + self.animatedView = nil + } + + self.titleLabel.text = title + if subTitle != nil { + self.subTitleTextView.text = subTitle + } + buttons = [] + if buttonTitle.isEmpty == false { + let button: UIButton = UIButton(type: UIButtonType.custom) + button.setTitle(buttonTitle, for: UIControlState()) + button.backgroundColor = buttonColor + button.isUserInteractionEnabled = true + button.tag = 0 + buttons.append(button) + } + + if otherButtonTitle != nil && otherButtonTitle!.isEmpty == false { + let button: UIButton = UIButton(type: UIButtonType.custom) + button.setTitle(otherButtonTitle, for: UIControlState()) + button.backgroundColor = otherButtonColor + button.addTarget(self, action: #selector(SweetAlert.pressed(_:)), for: UIControlEvents.touchUpInside) + button.tag = 1 + buttons.append(button) + } + + resizeAndRelayout() + if SweetAlertContext.shouldNotAnimate == true { + //Do not animate Alert + if self.animatedView != nil { + self.animatedView!.animate() } + } + else { + animateAlert() + } } - + func animateAlert() { - + view.alpha = 0; UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.alpha = 1.0; }) - + let previousTransform = self.contentView.transform self.contentView.layer.transform = CATransform3DMakeScale(0.9, 0.9, 0.0); UIView.animate(withDuration: 0.2, animations: { () -> Void in self.contentView.layer.transform = CATransform3DMakeScale(1.1, 1.1, 0.0); + }, completion: { (Bool) -> Void in + UIView.animate(withDuration: 0.1, animations: { () -> Void in + self.contentView.layer.transform = CATransform3DMakeScale(0.9, 0.9, 0.0); }, completion: { (Bool) -> Void in UIView.animate(withDuration: 0.1, animations: { () -> Void in - self.contentView.layer.transform = CATransform3DMakeScale(0.9, 0.9, 0.0); - }, completion: { (Bool) -> Void in - UIView.animate(withDuration: 0.1, animations: { () -> Void in - self.contentView.layer.transform = CATransform3DMakeScale(1.0, 1.0, 0.0); - if self.animatedView != nil { - self.animatedView!.animate() - } - - }, completion: { (Bool) -> Void in - - self.contentView.transform = previousTransform - }) - }) - }) + self.contentView.layer.transform = CATransform3DMakeScale(1.0, 1.0, 0.0); + if self.animatedView != nil { + self.animatedView!.animate() + } + + }, completion: { (Bool) -> Void in + + self.contentView.transform = previousTransform + }) + }) + }) } fileprivate struct SweetAlertContext { @@ -336,9 +336,7 @@ open class SweetAlert: UIViewController { } // MARK: - - // MARK: Animatable Views - class AnimatableView: UIView { func animate(){ print("Should overide by subclasss", terminator: "") @@ -349,13 +347,13 @@ class CancelAnimatedView: AnimatableView { var circleLayer = CAShapeLayer() var crossPathLayer = CAShapeLayer() - + override required init(frame: CGRect) { super.init(frame: frame) setupLayers() var t = CATransform3DIdentity; t.m34 = 1.0 / -500.0; - t = CATransform3DRotate(t, CGFloat(90.0 * M_PI / 180.0), 1, 0, 0); + t = CATransform3DRotate(t, CGFloat(90.0 * Double.pi / 180.0), 1, 0, 0); circleLayer.transform = t crossPathLayer.opacity = 0.0 } @@ -368,14 +366,14 @@ class CancelAnimatedView: AnimatableView { fatalError("init(coder:) has not been implemented") } - fileprivate var outlineCircle: CGPath { + fileprivate var outlineCircle: CGPath { let path = UIBezierPath() - let startAngle: CGFloat = CGFloat((0) / 180.0 * M_PI) //0 - let endAngle: CGFloat = CGFloat((360) / 180.0 * M_PI) //360 + let startAngle: CGFloat = CGFloat((0) / 180.0 * Double.pi) //0 + let endAngle: CGFloat = CGFloat((360) / 180.0 * Double.pi) //360 path.addArc(withCenter: CGPoint(x: self.frame.size.width/2.0, y: self.frame.size.width/2.0), radius: self.frame.size.width/2.0, startAngle: startAngle, endAngle: endAngle, clockwise: false) return path.cgPath - } + } fileprivate var crossPath: CGPath { let path = UIBezierPath() @@ -406,18 +404,18 @@ class CancelAnimatedView: AnimatableView { crossPathLayer.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height) crossPathLayer.position = CGPoint(x: self.frame.size.width/2.0, y: self.frame.size.height/2.0) self.layer.addSublayer(crossPathLayer) - + } override func animate() { var t = CATransform3DIdentity; t.m34 = 1.0 / -500.0; - t = CATransform3DRotate(t, CGFloat(90.0 * M_PI / 180.0), 1, 0, 0); + t = CATransform3DRotate(t, CGFloat(90.0 * Double.pi / 180.0), 1, 0, 0); var t2 = CATransform3DIdentity; t2.m34 = 1.0 / -500.0; - t2 = CATransform3DRotate(t2, CGFloat(-M_PI), 1, 0, 0); - + t2 = CATransform3DRotate(t2, CGFloat(-Double.pi), 1, 0, 0); + let animation = CABasicAnimation(keyPath: "transform") let time = 0.3 animation.duration = time; @@ -430,7 +428,7 @@ class CancelAnimatedView: AnimatableView { var scale = CATransform3DIdentity; scale = CATransform3DScale(scale, 0.3, 0.3, 0) - + let crossAnimation = CABasicAnimation(keyPath: "transform") crossAnimation.duration = 0.3; @@ -472,8 +470,8 @@ class InfoAnimatedView: AnimatableView { var outlineCircle: CGPath { let path = UIBezierPath() - let startAngle: CGFloat = CGFloat((0) / 180.0 * M_PI) //0 - let endAngle: CGFloat = CGFloat((360) / 180.0 * M_PI) //360 + let startAngle: CGFloat = CGFloat((0) / 180.0 * Double.pi) //0 + let endAngle: CGFloat = CGFloat((360) / 180.0 * Double.pi) //360 path.addArc(withCenter: CGPoint(x: self.frame.size.width/2.0, y: self.frame.size.width/2.0), radius: self.frame.size.width/2.0, startAngle: startAngle, endAngle: endAngle, clockwise: false) let factor:CGFloat = self.frame.size.width / 1.5 @@ -529,20 +527,20 @@ class SuccessAnimatedView: AnimatableView { override func layoutSubviews() { setupLayers() } - + var outlineCircle: CGPath { let path = UIBezierPath() - let startAngle: CGFloat = CGFloat((0) / 180.0 * M_PI) //0 - let endAngle: CGFloat = CGFloat((360) / 180.0 * M_PI) //360 + let startAngle: CGFloat = CGFloat((0) / 180.0 * Double.pi) //0 + let endAngle: CGFloat = CGFloat((360) / 180.0 * Double.pi) //360 path.addArc(withCenter: CGPoint(x: self.frame.size.width/2.0, y: self.frame.size.height/2.0), radius: self.frame.size.width/2.0, startAngle: startAngle, endAngle: endAngle, clockwise: false) return path.cgPath } var path: CGPath { let path = UIBezierPath() - let startAngle:CGFloat = CGFloat((60) / 180.0 * M_PI) //60 - let endAngle:CGFloat = CGFloat((200) / 180.0 * M_PI) //190 + let startAngle:CGFloat = CGFloat((60) / 180.0 * Double.pi) //60 + let endAngle:CGFloat = CGFloat((200) / 180.0 * Double.pi) //190 path.addArc(withCenter: CGPoint(x: self.frame.size.width/2.0, y: self.frame.size.height/2.0), radius: self.frame.size.width/2.0, startAngle: startAngle, endAngle: endAngle, clockwise: false) path.addLine(to: CGPoint(x: 36.0 - 10.0 ,y: 60.0 - 10.0)) path.addLine(to: CGPoint(x: 85.0 - 20.0, y: 30.0 - 20.0)) @@ -553,7 +551,7 @@ class SuccessAnimatedView: AnimatableView { func setupLayers() { outlineLayer.position = CGPoint(x: 0, - y: 0); + y: 0); outlineLayer.path = outlineCircle outlineLayer.fillColor = UIColor.clear.cgColor; outlineLayer.strokeColor = UIColor(red: 150.0/255.0, green: 216.0/255.0, blue: 115.0/255.0, alpha: 1.0).cgColor; @@ -563,7 +561,7 @@ class SuccessAnimatedView: AnimatableView { self.layer.addSublayer(outlineLayer) circleLayer.position = CGPoint(x: 0, - y: 0); + y: 0); circleLayer.path = path circleLayer.fillColor = UIColor.clear.cgColor; circleLayer.strokeColor = UIColor(red: 150.0/255.0, green: 216.0/255.0, blue: 115.0/255.0, alpha: 1.0).cgColor; @@ -611,4 +609,3 @@ extension UIColor { ) } } -