CustomTextView.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // CustomTextView.swift
  3. // Qmera
  4. //
  5. // Created by Akhmad Al Qindi Irsyam on 27/09/21.
  6. //
  7. import UIKit
  8. class CustomTextView: UITextView {
  9. override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
  10. let menuController = UIMenuController.shared
  11. if var menuItems = menuController.menuItems,
  12. (menuItems.map { $0.action }).elementsEqual([#selector(toggleBoldface), #selector(toggleItalics), #selector(toggleUnderline)]) {
  13. menuItems.append(UIMenuItem(title: "Strikethrough", action: #selector(toggleStrikethrough)))
  14. menuController.menuItems = menuItems
  15. }
  16. return super.canPerformAction(action, withSender: sender)
  17. }
  18. @objc func toggleStrikethrough(_ sender: Any?) {
  19. if let range = self.selectedTextRange {
  20. let startPosition = self.offset(from: self.beginningOfDocument, to: range.start)
  21. if startPosition == 0 || checkCharBefore(char: self.text.substring(from: startPosition - 1, to: startPosition - 1)) {
  22. self.replace(self.textRange(from: range.start, to: range.end)!, withText: "~\(self.text(in: range)!)~")
  23. } else {
  24. self.replace(self.textRange(from: range.start, to: range.end)!, withText: " ~\(self.text(in: range)!)~")
  25. }
  26. UIMenuController.shared.isMenuVisible = false
  27. }
  28. }
  29. override func toggleBoldface(_ sender: Any?) {
  30. if let range = self.selectedTextRange {
  31. let startPosition = self.offset(from: self.beginningOfDocument, to: range.start)
  32. if startPosition == 0 || checkCharBefore(char: self.text.substring(from: startPosition - 1, to: startPosition - 1)) {
  33. self.replace(self.textRange(from: range.start, to: range.end)!, withText: "*\(self.text(in: range)!)*")
  34. } else {
  35. self.replace(self.textRange(from: range.start, to: range.end)!, withText: " *\(self.text(in: range)!)*")
  36. }
  37. UIMenuController.shared.isMenuVisible = false
  38. }
  39. }
  40. override func toggleUnderline(_ sender: Any?) {
  41. if let range = self.selectedTextRange {
  42. let startPosition = self.offset(from: self.beginningOfDocument, to: range.start)
  43. if startPosition == 0 || checkCharBefore(char: self.text.substring(from: startPosition - 1, to: startPosition - 1)) {
  44. self.replace(self.textRange(from: range.start, to: range.end)!, withText: "^\(self.text(in: range)!)^")
  45. } else {
  46. self.replace(self.textRange(from: range.start, to: range.end)!, withText: " ^\(self.text(in: range)!)^")
  47. }
  48. UIMenuController.shared.isMenuVisible = false
  49. }
  50. }
  51. override func toggleItalics(_ sender: Any?) {
  52. if let range = self.selectedTextRange {
  53. let startPosition = self.offset(from: self.beginningOfDocument, to: range.start)
  54. if startPosition == 0 || checkCharBefore(char: self.text.substring(from: startPosition - 1, to: startPosition - 1)) {
  55. self.replace(self.textRange(from: range.start, to: range.end)!, withText: "_\(self.text(in: range)!)_")
  56. } else {
  57. self.replace(self.textRange(from: range.start, to: range.end)!, withText: " _\(self.text(in: range)!)_")
  58. }
  59. UIMenuController.shared.isMenuVisible = false
  60. }
  61. }
  62. func checkCharBefore(char: String) -> Bool {
  63. return char == " " || char == "\n"
  64. }
  65. }