Skip to content

Commit

Permalink
Release 1.1.0 (#4)
Browse files Browse the repository at this point in the history
Release `1.1.0`
  • Loading branch information
ns-vasilev authored Jan 27, 2025
2 parents ecd9312 + 565ecd8 commit 3361515
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 39 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ jobs:
name: "iOS 18.1"
xcode: "Xcode_16.1"
runsOn: macOS-14
- destination: "OS=18.0,name=iPhone 16 Pro"
name: "iOS 18.0"
xcode: "Xcode_16.0"
runsOn: macOS-14
steps:
- uses: actions/checkout@v4
- name: ${{ matrix.name }}
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Change Log
All notable changes to this project will be documented in this file.

#### 1.x Releases
- `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)
Released on 2025-01-27.

#### Added
- Implement adding an action to a `UITextField`.
- Added in Pull Request [#3](https://github.com/space-code/flex-ui/pull/3).

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

Expand Down
38 changes: 4 additions & 34 deletions Sources/FlexUI/Classes/Extensions/FlexUI+UIButton.swift
Original file line number Diff line number Diff line change
@@ -1,41 +1,11 @@
//
// flex-ui
// Copyright © 2024 Space Code. All rights reserved.
// Copyright © 2025 Space Code. All rights reserved.
//

import UIKit

// MARK: - ButtonCommand

/// A private class that wraps a closure to be executed as an action for a `UIButton`.
/// This class allows associating arbitrary closure actions with buttons, and is used internally
/// to manage custom button actions in the `FlexUI` extension.
private final class ButtonCommand {
// MARK: Properties

/// The closure that will be executed when the button action is triggered.
let block: () -> Void

// MARK: Initialization

/// Initializes a new instance of `ButtonCommand` with the provided closure.
///
/// - Parameter block: The closure to be executed when the button is tapped.
init(block: @escaping () -> Void) {
self.block = block
}

// MARK: Actions

/// The action method that is triggered when the associated button's event occurs.
/// It executes the stored closure.
@objc
func action() {
block()
}
}

@MainActor private let kMapTable = NSMapTable<AnyObject, ButtonCommand>.weakToStrongObjects()
@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.
Expand Down Expand Up @@ -251,7 +221,7 @@ public extension FlexUI where Component: UIButton {
return self
}

let buttonCommand = ButtonCommand(block: command)
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)
Expand All @@ -271,7 +241,7 @@ public extension FlexUI where Component: UIButton {
return self
}

let buttonCommand = ButtonCommand { [weak component] in
let buttonCommand = Command { [weak component] in
if let component = component {
command(component)
}
Expand Down
53 changes: 52 additions & 1 deletion Sources/FlexUI/Classes/Extensions/FlexUI+UITextField.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//
// flex-ui
// Copyright © 2024 Space Code. All rights reserved.
// Copyright © 2025 Space Code. All rights reserved.
//

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 @@ -140,4 +142,53 @@ 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
}
}
34 changes: 34 additions & 0 deletions Sources/FlexUI/Classes/Model/Command.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// flex-ui
// Copyright © 2025 Space Code. All rights reserved.
//

import Foundation

/// A private class that wraps a closure to be executed as an action for a `UIControl`.
/// This class allows associating arbitrary closure actions with buttons, and is used internally
/// to manage custom button actions in the `FlexUI` extension.
final class Command {
// MARK: Properties

/// The closure that will be executed when the button action is triggered.
let block: () -> Void

// MARK: Initialization

/// Initializes a new instance of `Command` with the provided closure.
///
/// - Parameter block: The closure to be executed when the button is tapped.
init(block: @escaping () -> Void) {
self.block = block
}

// MARK: Actions

/// The action method that is triggered when the associated button's event occurs.
/// It executes the stored closure.
@objc
func action() {
block()
}
}

0 comments on commit 3361515

Please sign in to comment.