CustomAlertView.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // CustomAlertView.swift
  3. // PDF Reader Pro
  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. // style.lineHeightMultiple = 1.32
  25. style.alignment = .center
  26. var fontSize: CGFloat = 0
  27. var offsetSize = CGSize.zero
  28. if alertStyle == .black {
  29. fontSize = 16
  30. } else {
  31. fontSize = 12
  32. }
  33. let attributes: [NSAttributedString.Key: Any] = [
  34. .font: NSFont.systemFont(ofSize: fontSize),
  35. .paragraphStyle: style
  36. ]
  37. let maxSize = CGSize(width: min(supverView.frame.size.width - 80, 500), height: supverView.frame.size.height - 40)
  38. let size = message.boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], attributes: attributes).size
  39. let ceilSize = NSSize(width: ceil(size.width), height: ceil(size.height))
  40. if alertStyle == .black {
  41. offsetSize = NSSize(width: ceilSize.width + 60, height: ceilSize.height + 30)
  42. view.frame = NSRect(x: (supverView.frame.size.width - offsetSize.width) / 2,
  43. y: (supverView.frame.size.height - offsetSize.height) / 2,
  44. width: offsetSize.width, height: offsetSize.height)
  45. } else {
  46. offsetSize = NSSize(width: ceilSize.width + ceilSize.height + 14 + 10, height: ceilSize.height + 14)
  47. view.frame = NSRect(x: (supverView.frame.size.width - offsetSize.width) / 2,
  48. y: (supverView.frame.size.height - offsetSize.height) - 10,
  49. width: offsetSize.width, height: offsetSize.height)
  50. }
  51. supverView.addSubview(view)
  52. view.wantsLayer = true
  53. let messageLabel: NSTextField
  54. if alertStyle == .black {
  55. view.layer?.cornerRadius = 8
  56. if let color1 = color {
  57. view.layer?.backgroundColor = color1.cgColor
  58. } else {
  59. view.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.7).cgColor
  60. }
  61. messageLabel = NSTextField(frame: NSRect(x: 15, y: 15, width: ceilSize.width + 30, height: ceilSize.height))
  62. } else {
  63. view.layer?.cornerRadius = view.frame.size.height / 2
  64. if let color1 = color {
  65. view.layer?.backgroundColor = color1.cgColor
  66. } else {
  67. view.layer?.backgroundColor = NSColor(red: 78/255.0, green: 163/255.0, blue: 255/255.0, alpha: 1).cgColor
  68. }
  69. messageLabel = NSTextField(frame: NSRect(x: view.frame.size.height / 2, y: 7, width: ceilSize.width + 10, height: ceilSize.height))
  70. }
  71. messageLabel.font = NSFont.systemFont(ofSize: fontSize)
  72. messageLabel.textColor = NSColor.white
  73. messageLabel.backgroundColor = NSColor.clear
  74. messageLabel.isBordered = false
  75. messageLabel.isEditable = false
  76. messageLabel.usesSingleLineMode = false
  77. messageLabel.cell?.wraps = true
  78. messageLabel.alignment = .center
  79. messageLabel.attributedStringValue = NSMutableAttributedString(string: NSLocalizedString(message, comment: ""),
  80. attributes: [NSAttributedString.Key.paragraphStyle: style,
  81. NSAttributedString.Key.font : NSFont.systemFont(ofSize: fontSize)])
  82. view.addSubview(messageLabel)
  83. view.alphaAnimation(from: 0, to: 1, duration: 0.3) {
  84. DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
  85. view.alphaAnimation(from: 1.0, to: 0.0, duration: 0.3) {
  86. view.removeFromSuperview()
  87. }
  88. }
  89. }
  90. return view
  91. }
  92. static func alertView(message: String, fromView supverView: NSView, withStyle alertStyle: KMCustomAlertStyle) -> CustomAlertView? {
  93. return CustomAlertView.alertView(message: message, fromView: supverView, withStyle: alertStyle, backgroundColor: nil)
  94. }
  95. func alphaAnimation(from fromValue: Float, to toValue: Float, duration: Float, finishedBlock block: @escaping () -> Void) {
  96. let flash = CABasicAnimation(keyPath: "opacity")
  97. flash.fromValue = NSNumber(value: fromValue)
  98. flash.toValue = NSNumber(value: toValue)
  99. flash.duration = 0.5
  100. self.layer?.add(flash, forKey: "flashAnimation")
  101. DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(duration)) {
  102. block()
  103. }
  104. }
  105. }