CustomAlertView.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // CustomAlertView.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2023/10/7.
  6. //
  7. import Cocoa
  8. enum KMCustomAlertStyle: Int {
  9. case black
  10. case blue
  11. }
  12. class CustomAlertView: NSView {
  13. override func draw(_ dirtyRect: NSRect) {
  14. super.draw(dirtyRect)
  15. // Drawing code here.
  16. }
  17. static func alertView(message: String, fromView supverView: NSView, withStyle alertStyle: KMCustomAlertStyle, backgroundColor color: NSColor?) -> CustomAlertView? {
  18. if alertStyle != .black && alertStyle != .blue {
  19. return nil
  20. }
  21. let view = CustomAlertView()
  22. let style = NSMutableParagraphStyle()
  23. style.lineBreakMode = .byWordWrapping
  24. var fontSize: CGFloat = 0
  25. var offsetSize = CGSize.zero
  26. if alertStyle == .black {
  27. fontSize = 16
  28. } else {
  29. fontSize = 12
  30. }
  31. let attributes: [NSAttributedString.Key: Any] = [
  32. .font: NSFont.systemFont(ofSize: fontSize),
  33. .paragraphStyle: style
  34. ]
  35. let maxSize = CGSize(width: min(supverView.frame.size.width - 80, 500), height: supverView.frame.size.height - 40)
  36. let size = message.boundingRect(with: maxSize, options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin, .usesFontLeading], attributes: attributes).size
  37. let ceilSize = NSSize(width: ceil(size.width), height: ceil(size.height))
  38. if alertStyle == .black {
  39. offsetSize = NSSize(width: ceilSize.width + 60, height: ceilSize.height + 30)
  40. view.frame = NSRect(x: (supverView.frame.size.width - offsetSize.width) / 2,
  41. y: (supverView.frame.size.height - offsetSize.height) / 2,
  42. width: offsetSize.width, height: offsetSize.height)
  43. } else {
  44. offsetSize = NSSize(width: ceilSize.width + ceilSize.height + 14 + 10, height: ceilSize.height + 14)
  45. view.frame = NSRect(x: (supverView.frame.size.width - offsetSize.width) / 2,
  46. y: (supverView.frame.size.height - offsetSize.height) - 10,
  47. width: offsetSize.width, height: offsetSize.height)
  48. }
  49. supverView.addSubview(view)
  50. view.wantsLayer = true
  51. let messageLabel: NSTextField
  52. if alertStyle == .black {
  53. view.layer?.cornerRadius = 8
  54. if let color1 = color {
  55. view.layer?.backgroundColor = color1.cgColor
  56. } else {
  57. view.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.7).cgColor
  58. }
  59. messageLabel = NSTextField(frame: NSRect(x: 15, y: 15, width: ceilSize.width + 30, height: ceilSize.height))
  60. } else {
  61. view.layer?.cornerRadius = view.frame.size.height / 2
  62. if let color1 = color {
  63. view.layer?.backgroundColor = color1.cgColor
  64. } else {
  65. view.layer?.backgroundColor = NSColor(red: 78/255.0, green: 163/255.0, blue: 255/255.0, alpha: 1).cgColor
  66. }
  67. messageLabel = NSTextField(frame: NSRect(x: view.frame.size.height / 2, y: 7, width: ceilSize.width + 10, height: ceilSize.height))
  68. }
  69. messageLabel.font = NSFont.systemFont(ofSize: fontSize)
  70. messageLabel.textColor = NSColor.white
  71. messageLabel.backgroundColor = NSColor.clear
  72. messageLabel.isBordered = false
  73. messageLabel.isEditable = false
  74. if #available(OSX 10.11, *) {
  75. messageLabel.lineBreakMode = .byWordWrapping
  76. }
  77. messageLabel.alignment = .center
  78. messageLabel.stringValue = message
  79. view.addSubview(messageLabel)
  80. view.alphaAnimation(from: 0, to: 1, duration: 0.3) {
  81. DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
  82. view.alphaAnimation(from: 1.0, to: 0.0, duration: 0.3) {
  83. view.removeFromSuperview()
  84. }
  85. }
  86. }
  87. return view
  88. }
  89. static func alertView(message: String, fromView supverView: NSView, withStyle alertStyle: KMCustomAlertStyle) -> CustomAlertView? {
  90. return CustomAlertView.alertView(message: message, fromView: supverView, withStyle: alertStyle, backgroundColor: nil)
  91. }
  92. func alphaAnimation(from fromValue: Float, to toValue: Float, duration: Float, finishedBlock block: @escaping () -> Void) {
  93. let flash = CABasicAnimation(keyPath: "opacity")
  94. flash.fromValue = NSNumber(value: fromValue)
  95. flash.toValue = NSNumber(value: toValue)
  96. flash.duration = 0.5
  97. self.layer?.add(flash, forKey: "flashAnimation")
  98. DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(duration)) {
  99. block()
  100. }
  101. }
  102. }