NCButton.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  3. // SPDX-License-Identifier: GPL-3.0-or-later
  4. //
  5. import Foundation
  6. import UIKit
  7. import SwiftUI
  8. struct NCButtonSwiftUI: View {
  9. @State var title: String
  10. @State var action: () -> Void
  11. @State var style: NCButtonStyle
  12. @State var height: CGFloat
  13. @Binding var disabled: Bool
  14. enum NCButtonStyle: Int {
  15. case primary = 0
  16. case secondary
  17. case tertiary
  18. case destructive
  19. }
  20. var body: some View {
  21. Button(action: action, label: {
  22. Text(title)
  23. .bold()
  24. .foregroundColor(titleColorForStyle(style: style).opacity(disabled ? 0.5 : 1))
  25. .padding(.vertical, 4)
  26. .padding(.horizontal, 40)
  27. .frame(height: height)
  28. .background(backgroundColorForStyle(style: style).opacity(disabled ? 0.5 : 1))
  29. .cornerRadius(height / 2)
  30. .overlay(
  31. RoundedRectangle(cornerRadius: 20)
  32. .stroke(borderColorForStyle(style: style).opacity(disabled ? 0.5 : 1), lineWidth: borderWidthForStyle(style: style))
  33. )
  34. })
  35. .disabled(disabled)
  36. }
  37. func backgroundColorForStyle(style: NCButtonStyle) -> Color {
  38. switch style {
  39. case .primary:
  40. return Color(NCAppBranding.themeColor())
  41. case .secondary:
  42. return .clear
  43. case .tertiary:
  44. return .clear
  45. case .destructive:
  46. return .red
  47. }
  48. }
  49. func titleColorForStyle(style: NCButtonStyle) -> Color {
  50. switch style {
  51. case .primary:
  52. return Color(NCAppBranding.themeTextColor())
  53. case .secondary:
  54. return Color(NCAppBranding.elementColor())
  55. case .tertiary:
  56. return .primary
  57. case .destructive:
  58. return .white
  59. }
  60. }
  61. func borderColorForStyle(style: NCButtonStyle) -> Color {
  62. switch style {
  63. case .primary:
  64. return .clear
  65. case .secondary:
  66. return Color(NCAppBranding.elementColor())
  67. case .tertiary:
  68. return Color(NCAppBranding.placeholderColor())
  69. case .destructive:
  70. return .clear
  71. }
  72. }
  73. func borderWidthForStyle(style: NCButtonStyle) -> CGFloat {
  74. switch style {
  75. case .primary:
  76. return 0.0
  77. case .secondary:
  78. return 1.0
  79. case .tertiary:
  80. return 1.0
  81. case .destructive:
  82. return 0.0
  83. }
  84. }
  85. }
  86. @objc class NCButton: UIButton {
  87. enum NCButtonStyle: Int {
  88. case primary = 0
  89. case secondary
  90. case tertiary
  91. case destructive
  92. }
  93. var style: NCButtonStyle?
  94. var buttonAction: Selector?
  95. override init(frame: CGRect) {
  96. super.init(frame: frame)
  97. commonInit()
  98. }
  99. required init?(coder aDecoder: NSCoder) {
  100. super.init(coder: aDecoder)
  101. commonInit()
  102. }
  103. func commonInit() {
  104. self.layer.cornerRadius = self.frame.height / 2
  105. self.layer.masksToBounds = true
  106. self.setButtonStyle(style: .primary)
  107. }
  108. override func layoutSubviews() {
  109. super.layoutSubviews()
  110. self.layer.cornerRadius = self.frame.height / 2
  111. }
  112. func backgroundColorForStyle(style: NCButtonStyle) -> UIColor {
  113. switch style {
  114. case .primary:
  115. return NCAppBranding.themeColor()
  116. case .secondary:
  117. return .clear
  118. case .tertiary:
  119. return .clear
  120. case .destructive:
  121. return .systemRed
  122. }
  123. }
  124. func setButtonStyle(style: NCButtonStyle) {
  125. self.style = style
  126. switch style {
  127. case .primary:
  128. self.setTitleColor(NCAppBranding.themeTextColor(), for: .normal)
  129. self.setTitleColor(NCAppBranding.themeTextColor().withAlphaComponent(0.5), for: .disabled)
  130. self.backgroundColor = backgroundColorForStyle(style: .primary)
  131. self.layer.borderWidth = 0.0
  132. case .secondary:
  133. self.setTitleColor(NCAppBranding.elementColor(), for: .normal)
  134. self.setTitleColor(NCAppBranding.elementColor().withAlphaComponent(0.5), for: .disabled)
  135. self.backgroundColor = backgroundColorForStyle(style: .secondary)
  136. self.layer.borderColor = NCAppBranding.elementColor().cgColor
  137. self.layer.borderWidth = 1.0
  138. case .tertiary:
  139. self.setTitleColor(.label, for: .normal)
  140. self.setTitleColor(.label.withAlphaComponent(0.5), for: .disabled)
  141. self.backgroundColor = backgroundColorForStyle(style: .tertiary)
  142. self.layer.borderColor = NCAppBranding.placeholderColor().cgColor
  143. self.layer.borderWidth = 1.0
  144. case .destructive:
  145. self.setTitleColor(.white, for: .normal)
  146. self.setTitleColor(.white.withAlphaComponent(0.5), for: .disabled)
  147. self.backgroundColor = backgroundColorForStyle(style: .destructive)
  148. self.layer.borderWidth = 0.0
  149. }
  150. }
  151. func setButtonEnabled(enabled: Bool) {
  152. if let style = self.style, backgroundColorForStyle(style: style) != .clear {
  153. self.backgroundColor = enabled ? backgroundColorForStyle(style: style) : backgroundColorForStyle(style: style).withAlphaComponent(0.5)
  154. }
  155. if let borderColor = self.layer.borderColor {
  156. self.layer.borderColor = UIColor(cgColor: borderColor).withAlphaComponent(enabled ? 1 : 0.5).cgColor
  157. }
  158. self.isEnabled = enabled
  159. }
  160. func setButtonAction(target: Any?, selector: Selector) {
  161. self.removeTarget(target, action: buttonAction, for: .touchUpInside)
  162. self.addTarget(target, action: selector, for: .touchUpInside)
  163. buttonAction = selector
  164. }
  165. }