|
1 | 1 | // |
2 | 2 | // flex-ui |
3 | | -// Copyright © 2024 Space Code. All rights reserved. |
| 3 | +// Copyright © 2025 Space Code. All rights reserved. |
4 | 4 | // |
5 | 5 |
|
6 | 6 | import UIKit |
7 | 7 |
|
| 8 | +@MainActor private let kMapTable = NSMapTable<AnyObject, Command>.weakToStrongObjects() |
| 9 | + |
8 | 10 | public extension FlexUI where Component: UITextField { |
9 | 11 | /// Sets the font of the text field. |
10 | 12 | /// |
@@ -140,4 +142,53 @@ public extension FlexUI where Component: UITextField { |
140 | 142 | component.adjustsFontSizeToFitWidth = true |
141 | 143 | return self |
142 | 144 | } |
| 145 | + |
| 146 | + /// Adds a command to be executed when a specified event occurs on the UIControl component. |
| 147 | + /// The method is annotated with `@discardableResult` to allow the return value to be ignored, |
| 148 | + /// and `@MainActor` to ensure it runs on the main thread. |
| 149 | + /// |
| 150 | + /// - Parameters: |
| 151 | + /// - command: A closure to be executed when the event occurs. Can be `nil`, in which case no action is added. |
| 152 | + /// - event: The `UIControl.Event` that triggers the command. |
| 153 | + /// - Returns: The instance of `Self` to allow method chaining. |
| 154 | + @discardableResult |
| 155 | + @MainActor |
| 156 | + func add(command: (() -> Void)?, event: UIControl.Event) -> Self { |
| 157 | + guard let command = command else { |
| 158 | + return self |
| 159 | + } |
| 160 | + |
| 161 | + let buttonCommand = Command(block: command) |
| 162 | + component.removeTarget(nil, action: nil, for: event) |
| 163 | + component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event) |
| 164 | + kMapTable.setObject(buttonCommand, forKey: component) |
| 165 | + return self |
| 166 | + } |
| 167 | + |
| 168 | + /// Adds a command to be executed when a specified event occurs on the `UITextField` component. |
| 169 | + /// The method is annotated with `@discardableResult` to allow the return value to be ignored, |
| 170 | + /// and `@MainActor` to ensure it runs on the main thread. |
| 171 | + /// |
| 172 | + /// - Parameters: |
| 173 | + /// - command: A closure that receives the `UITextField` as a parameter when the event occurs. Can be `nil`. |
| 174 | + /// - event: The `UIControl.Event` that triggers the command. |
| 175 | + /// - Returns: The instance of `Self` to allow method chaining. |
| 176 | + @discardableResult |
| 177 | + @MainActor |
| 178 | + func add(command: ((UITextField) -> Void)?, event: UIControl.Event) -> Self { |
| 179 | + guard let command = command else { |
| 180 | + return self |
| 181 | + } |
| 182 | + |
| 183 | + let buttonCommand = Command { [weak component] in |
| 184 | + if let component = component { |
| 185 | + command(component) |
| 186 | + } |
| 187 | + } |
| 188 | + |
| 189 | + component.removeTarget(nil, action: nil, for: event) |
| 190 | + component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event) |
| 191 | + kMapTable.setObject(buttonCommand, forKey: component) |
| 192 | + return self |
| 193 | + } |
143 | 194 | } |
0 commit comments