Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@
All notable changes to this project will be documented in this file.

#### 1.x Releases
- `1.2.x` Releases - [1.2.0](#120)
- `1.1.x` Releases - [1.1.0](#110)
- `1.0.x` Releases - [1.0.0](#100)

## [1.1.0](https://github.com/space-code/flare/releases/tag/1.1.0)
## [1.2.0](https://github.com/space-code/flex-ui/releases/tag/1.2.0)
Released on 2025-02-15.

#### Added
- Implement the extension for the `UIControl` instance.
- Added in Pull Request [#6](https://github.com/space-code/flex-ui/pull/6).

## [1.1.0](https://github.com/space-code/flex-ui/releases/tag/1.1.0)
Released on 2025-01-27.

#### Added
Expand Down
47 changes: 0 additions & 47 deletions Sources/FlexUI/Classes/Extensions/FlexUI+UIButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import UIKit

@MainActor private let kMapTable = NSMapTable<AnyObject, Command>.weakToStrongObjects()

/// An extension to `FlexUI` that adds helper methods for configuring `UIButton` properties.
/// These methods allow for fluent configuration of button properties such as title, image, alignment, and actions.
public extension FlexUI where Component: UIButton {
Expand Down Expand Up @@ -207,49 +205,4 @@ public extension FlexUI where Component: UIButton {
component.isEnabled = isEnable
return self
}

/// Adds a custom command block to be executed when the button is tapped.
///
/// - Parameters:
/// - command: The closure to be executed.
/// - event: The event to associate the command with (default is `.touchUpInside`).
/// - Returns: The current instance of `FlexUI` for further configuration.
@discardableResult
@MainActor
func add(command: (() -> Void)?, event: UIControl.Event = .touchUpInside) -> Self {
guard let command = command else {
return self
}

let buttonCommand = Command(block: command)
component.removeTarget(nil, action: nil, for: event)
component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event)
kMapTable.setObject(buttonCommand, forKey: component)
return self
}

/// Adds a custom command block to be executed when the button is tapped, with access to the button itself.
///
/// - Parameters:
/// - command: The closure to be executed with the button as the parameter.
/// - event: The event to associate the command with.
/// - Returns: The current instance of `FlexUI` for further configuration.
@discardableResult
@MainActor
func add(command: ((UIButton) -> Void)?, event: UIControl.Event) -> Self {
guard let command = command else {
return self
}

let buttonCommand = Command { [weak component] in
if let component = component {
command(component)
}
}

component.removeTarget(nil, action: nil, for: event)
component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event)
kMapTable.setObject(buttonCommand, forKey: component)
return self
}
}
56 changes: 56 additions & 0 deletions Sources/FlexUI/Classes/Extensions/FlexUI+UIControl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// flex-ui
// Copyright © 2025 Space Code. All rights reserved.
//

import UIKit

@MainActor private let kMapTable = NSMapTable<AnyObject, Command>.weakToStrongObjects()

/// An extension to `FlexUI` that adds helper methods for configuring `UIControl` properties.
public extension FlexUI where Component: UIControl {
/// Adds a custom command block to be executed when the control is tapped.
///
/// - Parameters:
/// - command: The closure to be executed.
/// - event: The event to associate the command with (default is `.touchUpInside`).
/// - Returns: The current instance of `FlexUI` for further configuration.
@discardableResult
@MainActor
func add(command: (() -> Void)?, event: UIControl.Event = .touchUpInside) -> Self {
guard let command = command else {
return self
}

let componentCommand = Command(block: command)
component.removeTarget(nil, action: nil, for: event)
component.addTarget(componentCommand, action: #selector(componentCommand.action), for: event)
kMapTable.setObject(componentCommand, forKey: component)
return self
}

/// Adds a custom command block to be executed when the control is tapped, with access to the control itself.
///
/// - Parameters:
/// - command: The closure to be executed with the component as the parameter.
/// - event: The event to associate the command with.
/// - Returns: The current instance of `FlexUI` for further configuration.
@discardableResult
@MainActor
func add(command: ((Component) -> Void)?, event: UIControl.Event) -> Self {
guard let command = command else {
return self
}

let componentCommand = Command { [weak component] in
if let component = component {
command(component)
}
}

component.removeTarget(nil, action: nil, for: event)
component.addTarget(componentCommand, action: #selector(componentCommand.action), for: event)
kMapTable.setObject(componentCommand, forKey: component)
return self
}
}
51 changes: 0 additions & 51 deletions Sources/FlexUI/Classes/Extensions/FlexUI+UITextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import UIKit

@MainActor private let kMapTable = NSMapTable<AnyObject, Command>.weakToStrongObjects()

public extension FlexUI where Component: UITextField {
/// Sets the font of the text field.
///
Expand Down Expand Up @@ -142,53 +140,4 @@ public extension FlexUI where Component: UITextField {
component.adjustsFontSizeToFitWidth = true
return self
}

/// Adds a command to be executed when a specified event occurs on the UIControl component.
/// The method is annotated with `@discardableResult` to allow the return value to be ignored,
/// and `@MainActor` to ensure it runs on the main thread.
///
/// - Parameters:
/// - command: A closure to be executed when the event occurs. Can be `nil`, in which case no action is added.
/// - event: The `UIControl.Event` that triggers the command.
/// - Returns: The instance of `Self` to allow method chaining.
@discardableResult
@MainActor
func add(command: (() -> Void)?, event: UIControl.Event) -> Self {
guard let command = command else {
return self
}

let buttonCommand = Command(block: command)
component.removeTarget(nil, action: nil, for: event)
component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event)
kMapTable.setObject(buttonCommand, forKey: component)
return self
}

/// Adds a command to be executed when a specified event occurs on the `UITextField` component.
/// The method is annotated with `@discardableResult` to allow the return value to be ignored,
/// and `@MainActor` to ensure it runs on the main thread.
///
/// - Parameters:
/// - command: A closure that receives the `UITextField` as a parameter when the event occurs. Can be `nil`.
/// - event: The `UIControl.Event` that triggers the command.
/// - Returns: The instance of `Self` to allow method chaining.
@discardableResult
@MainActor
func add(command: ((UITextField) -> Void)?, event: UIControl.Event) -> Self {
guard let command = command else {
return self
}

let buttonCommand = Command { [weak component] in
if let component = component {
command(component)
}
}

component.removeTarget(nil, action: nil, for: event)
component.addTarget(buttonCommand, action: #selector(buttonCommand.action), for: event)
kMapTable.setObject(buttonCommand, forKey: component)
return self
}
}