Skip to content

Adding responsiveTextFieldPlaceholderColor modifier to update a ResponsiveTextField's placeholder color #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 2, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ extension ResponsiveTextField {
static let defaultValue: UIFont = .preferredFont(forTextStyle: .body)
}

fileprivate struct PlaceholderColorKey: EnvironmentKey {
static let defaultValue: UIColor = UIColor.black.withAlphaComponent(0.25)
}

fileprivate struct TextColorKey: EnvironmentKey {
static let defaultValue: UIColor = .black
}
Expand Down Expand Up @@ -49,6 +53,11 @@ extension EnvironmentValues {
set { self[ResponsiveTextField.FontKey.self] = newValue }
}

var textFieldPlaceholderColor: UIColor {
get { self[ResponsiveTextField.PlaceholderColorKey.self] }
set { self[ResponsiveTextField.PlaceholderColorKey.self] = newValue }
}

var textFieldTextColor: UIColor {
get { self[ResponsiveTextField.TextColorKey.self] }
set { self[ResponsiveTextField.TextColorKey.self] = newValue }
Expand Down
29 changes: 27 additions & 2 deletions Sources/ResponsiveTextField/ResponsiveTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CombineSchedulers
///
public struct ResponsiveTextField {
/// The text field placeholder string.
let placeholder: String
let placeholder: String?

/// A binding to the text state that will hold the typed text
let text: Binding<String>
Expand Down Expand Up @@ -56,6 +56,10 @@ public struct ResponsiveTextField {
@Environment(\.textFieldFont)
var font: UIFont

/// Sets the text field placeholder color - use the `.responsiveTextFieldPlaceholderColor()` modifier.
@Environment(\.textFieldPlaceholderColor)
var placeholderColor: UIColor

/// When `true`, configures the text field to automatically adjust its font based on the content size category.
///
/// - Note: When set to `true`, the underlying text field will not respond to changes to the `textFieldFont`
Expand Down Expand Up @@ -123,7 +127,7 @@ public struct ResponsiveTextField {
var standardEditActionHandler: StandardEditActionHandling<UITextField>?

public init(
placeholder: String,
placeholder: String?,
text: Binding<String>,
isSecure: Bool = false,
adjustsFontForContentSizeCategory: Bool = true,
Expand Down Expand Up @@ -330,6 +334,14 @@ extension ResponsiveTextField: UIViewRepresentable {
textField.textColor = textColor
textField.textAlignment = textAlignment
textField.returnKeyType = returnKeyType

if let placeholder {
textField.attributedPlaceholder = NSAttributedString(
string: placeholder,
attributes: [NSAttributedString.Key.foregroundColor: self.placeholderColor]
)
}

textField.delegate = context.coordinator
textField.addTarget(context.coordinator,
action: #selector(Coordinator.textFieldTextChanged(_:)),
Expand Down Expand Up @@ -357,6 +369,13 @@ extension ResponsiveTextField: UIViewRepresentable {
uiView.textColor = textColor
uiView.textAlignment = textAlignment

if let placeholder {
uiView.attributedPlaceholder = NSAttributedString(
string: placeholder,
attributes: [NSAttributedString.Key.foregroundColor: self.placeholderColor]
)
}

if !adjustsFontForContentSizeCategory {
// We should only support dynamic font changes using our own environment
// value if dynamic type support is disabled otherwise we will override
Expand Down Expand Up @@ -553,6 +572,11 @@ public extension View {
environment(\.textFieldTextColor, color)
}

/// Sets the text field placeholder text color on any child `ResponsiveTextField` views.
func responsiveTextFieldPlaceholderColor(_ color: UIColor) -> some View {
environment(\.textFieldPlaceholderColor, color)
}

/// Sets the text field text alignment on any child `ResponsiveTextField` views.
func responsiveTextFieldTextAlignment(_ alignment: NSTextAlignment) -> some View {
environment(\.textFieldTextAlignment, alignment)
Expand Down Expand Up @@ -603,6 +627,7 @@ struct ResponsiveTextField_Previews: PreviewProvider {
TextFieldPreview(configuration: .email, text: "[email protected]")
.responsiveTextFieldFont(.preferredFont(forTextStyle: .body))
.responsiveTextFieldTextColor(.systemBlue)
.responsiveTextFieldPlaceholderColor(.gray)
.previewLayout(.sizeThatFits)
.environment(\.sizeCategory, .extraExtraExtraLarge)
.previewDisplayName("Dynamic Font Size")
Expand Down
16 changes: 16 additions & 0 deletions Tests/ResponsiveTextFieldTests/ResponsiveTextFieldTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ final class ResponsiveTextFieldTests: XCTestCase {
)
}

@MainActor
func testPlaceholderTextFieldWithText() {
assertSnapshot(
of: ResponsiveTextField(
placeholder: "Placeholder Text",
text: .constant("Textfield with some text"),
isSecure: false,
firstResponderDemand: nil,
configuration: .empty
)
.responsiveTextFieldTextColor(UIColor.systemBlue)
.padding(),
as: .fixedSizeTextFieldImage
)
}

@MainActor
func testTextFieldCustomTextAlignment() {
assertSnapshot(
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading