Skip to content
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

[Refacto-557] Button: Add UIControl #588

Merged
merged 8 commits into from
Nov 22, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class ControlPropertyStates<PropertyType> {
/// Get the value for a state.
/// - Parameters:
/// - state: the state of the value
func value(forState state: ControlState) -> PropertyType? {
func value(for state: ControlState) -> PropertyType? {
switch state {
case .normal: return self.normalState.value
case .highlighted: return self.highlightedState.value
Expand All @@ -61,8 +61,8 @@ final class ControlPropertyStates<PropertyType> {

/// Get the value for the status of the control.
/// - Parameters:
/// - state: the status of the control
func value(forStatus status: ControlStatus) -> PropertyType? {
/// - status: the status of the control
func value(for status: ControlStatus) -> PropertyType? {
// isHighlighted has the highest priority,
// then isDisabled,
// then isSelected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class ControlPropertyStatesTests: XCTestCase {
states.setValue(expectedValue, for: state)

// WHEN
let value = states.value(forState: state)
let value = states.value(for: state)

// THEN
XCTAssertEqual(
Expand All @@ -45,7 +45,7 @@ final class ControlPropertyStatesTests: XCTestCase {
states.setValue(nil, for: state)

// WHEN
let value = states.value(forState: state)
let value = states.value(for: state)

// THEN
XCTAssertNil(
Expand Down Expand Up @@ -73,7 +73,7 @@ final class ControlPropertyStatesTests: XCTestCase {

var status = ControlStatus(isHighlighted: true)
states.setValue(highlightedValue, for: .highlighted)
var value = states.value(forStatus: status)
var value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -89,7 +89,7 @@ final class ControlPropertyStatesTests: XCTestCase {

status = ControlStatus(isHighlighted: true)
states.setValue(nil, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -106,7 +106,7 @@ final class ControlPropertyStatesTests: XCTestCase {
status = .init(isHighlighted: false)

states.setValue(highlightedValue, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand Down Expand Up @@ -134,7 +134,7 @@ final class ControlPropertyStatesTests: XCTestCase {

var status = ControlStatus(isDisabled: true)
states.setValue(disabledValue, for: .disabled)
var value = states.value(forStatus: status)
var value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -150,7 +150,7 @@ final class ControlPropertyStatesTests: XCTestCase {

status = ControlStatus(isDisabled: true)
states.setValue(nil, for: .disabled)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -167,7 +167,7 @@ final class ControlPropertyStatesTests: XCTestCase {
status = .init(isDisabled: false)

states.setValue(disabledValue, for: .disabled)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -186,7 +186,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(disabledValue, for: .disabled)
states.setValue(highlightedValue, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -205,7 +205,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(disabledValue, for: .disabled)
states.setValue(nil, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand Down Expand Up @@ -235,7 +235,7 @@ final class ControlPropertyStatesTests: XCTestCase {
// Test with .selected value and true isSelected status.

states.setValue(selectedValue, for: .selected)
var value = states.value(forStatus: status)
var value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -250,7 +250,7 @@ final class ControlPropertyStatesTests: XCTestCase {
// Test without .selected value and true isSelected status.

states.setValue(nil, for: .selected)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -267,7 +267,7 @@ final class ControlPropertyStatesTests: XCTestCase {
status = .init(isSelected: false)

states.setValue(selectedValue, for: .selected)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -286,7 +286,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(selectedValue, for: .selected)
states.setValue(highlightedValue, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -305,7 +305,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(selectedValue, for: .selected)
states.setValue(nil, for: .highlighted)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -324,7 +324,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(selectedValue, for: .selected)
states.setValue(disabledValue, for: .disabled)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -343,7 +343,7 @@ final class ControlPropertyStatesTests: XCTestCase {

states.setValue(selectedValue, for: .selected)
states.setValue(nil, for: .disabled)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -366,7 +366,7 @@ final class ControlPropertyStatesTests: XCTestCase {

var status = ControlStatus()
states.setValue(normalStateValue, for: .normal)
var value = states.value(forStatus: status)
var value = states.value(for: status)

// THEN
XCTAssertEqual(
Expand All @@ -382,7 +382,7 @@ final class ControlPropertyStatesTests: XCTestCase {

status = ControlStatus()
states.setValue(nil, for: .normal)
value = states.value(forStatus: status)
value = states.value(for: status)

// THEN
XCTAssertNil(
Expand Down
32 changes: 30 additions & 2 deletions core/Sources/Common/Control/UIView/UIControlStateImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,40 @@ final class UIControlStateImageView: UIImageView {

private let imageStates = ControlPropertyStates<UIImage>()

/// The image must be stored to lock the posibility to set the image directly like this **self.image = UIImage()**.
/// When the storedImage is set (always from **setImage** function), it set the image.
private var storedImage: UIImage? {
robergro marked this conversation as resolved.
Show resolved Hide resolved
didSet {
self.isImage = self.storedImage != nil
self.image = self.storedImage
}
}

// MARK: - Published

@Published var isImage: Bool = false

// MARK: - Override Properties

/// It's not possible to set the image outside this class.
/// The only possiblity to change the image is to use the **setImage(_: UIImage?, for: ControlState, on: UIControl)** function.
override var image: UIImage? {
get {
return super.image
}
set {
if newValue == self.storedImage {
super.image = newValue
}
}
}

// MARK: - Setter & Getter

/// The image for a state.
/// - parameter state: state of the image
func image(for state: ControlState) -> UIImage? {
return self.imageStates.value(forState: state)
return self.imageStates.value(for: state)
}

/// Set the image for a state.
Expand Down Expand Up @@ -50,6 +78,6 @@ final class UIControlStateImageView: UIImageView {
)

// Set the image from states
self.image = self.imageStates.value(forStatus: status)
self.storedImage = self.imageStates.value(for: status)
}
}
101 changes: 82 additions & 19 deletions core/Sources/Common/Control/UIView/UIControlStateLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,76 @@ final class UIControlStateLabel: UILabel {
private let attributedTextStates = ControlPropertyStates<NSAttributedString>()
private let textTypesStates = ControlPropertyStates<DisplayedTextType>()

/// The text must be stored to lock the posibility to set the text directly like this **self.text = "Text"**.
/// When the storedText is set (always from **setText** function), it set the text.
private var storedText: String? {
robergro marked this conversation as resolved.
Show resolved Hide resolved
didSet {
self.isText = self.storedText != nil
self.text = self.storedText

// Reset styles
if let storedTextFont = self.storedTextFont {
self.font = storedTextFont
}
if let storedTextColor = self.storedTextColor {
self.textColor = storedTextColor
}
}
}

/// The attributedText must be stored to lock the posibility to set the attributedText directly like this **self.attributedText = NSAttributedString()**.
/// When the storedAttributedText is set (always from **setAttributedText** function), it set the attributedText.
private var storedAttributedText: NSAttributedString? {
didSet {
self.isText = self.storedAttributedText != nil
self.attributedText = self.storedAttributedText
}
}

/// The storedTextFont is use to reset the font when a new text is set
/// because the previous text can be an attributedText
/// and attributedText has its own styles.
private var storedTextFont: UIFont?

/// The storedTextColor is use to reset the textColor when a new text is set
/// because the previous text can be an attributedText
/// and attributedText has its own styles.
private var storedTextColor: UIColor?

// MARK: - Published

@Published var isText: Bool = false

// MARK: - Override Properties

/// It's not possible to set the text outside this class.
/// The only possiblity to change the text is to use the **setText(_: String?, for: ControlState, on: UIControl)** function.
override var text: String? {
get {
return super.text
}
set {
// Set the attributedText only if the current come from setText
if newValue == self.storedText {
super.text = newValue
}
}
}

/// It's not possible to set the attributedText outside this class.
/// The only possiblity to change the attributedText is to use the **setAttributedText(_: NSAttributedString?, for: ControlState, on: UIControl)** function.
override var attributedText: NSAttributedString? {
get {
return super.attributedText
}
set {
// Set the attributedText only if the current come from setAttributedText
if newValue == self.storedAttributedText {
super.attributedText = newValue
}
}
}

override var font: UIFont! {
get {
return super.font
Expand Down Expand Up @@ -58,7 +123,7 @@ final class UIControlStateLabel: UILabel {
/// The text for a state.
/// - parameter state: state of the text
func text(for state: ControlState) -> String? {
return self.textStates.value(forState: state)
return self.textStates.value(for: state)
}

/// Set the text for a state.
Expand All @@ -81,7 +146,7 @@ final class UIControlStateLabel: UILabel {
/// The attributedText for a state.
/// - parameter state: state of the attributedText
func attributedText(for state: ControlState) -> NSAttributedString? {
return self.attributedTextStates.value(forState: state)
return self.attributedTextStates.value(for: state)
}

/// Set the attributedText of the button for a state.
Expand Down Expand Up @@ -113,26 +178,24 @@ final class UIControlStateLabel: UILabel {
)

// Get the current textType from status
let textType = textTypesStates.value(forStatus: status)
let textType = self.textTypesStates.value(for: status)
let textTypeContainsText = textType?.containsText ?? false

// Reset attributedText & text
self.attributedText = nil
self.text = nil
self.storedAttributedText = nil
self.storedText = nil

// Set the text or the attributedText from textType and states
switch textType {
case .text:
self.text = self.textStates.value(forStatus: status)
if let storedTextFont = self.storedTextFont {
self.font = storedTextFont
}
if let storedTextColor = self.storedTextColor {
self.textColor = storedTextColor
}
case .attributedText:
self.attributedText = self.attributedTextStates.value(forStatus: status)
default:
break
if let text = self.textStates.value(for: status),
textType == .text || !textTypeContainsText {
self.storedText = text

} else if let attributedText = self.attributedTextStates.value(for: status),
textType == .attributedText || !textTypeContainsText {
self.storedAttributedText = attributedText

} else { // No text to displayed
self.text = nil
}
}

Expand All @@ -144,7 +207,7 @@ final class UIControlStateLabel: UILabel {
guard let attributedText = self.attributedText else {
return false
}

// The attributedText contains attributes ?
return !attributedText.attributes(at: 0, effectiveRange: nil).isEmpty
}
Expand Down
Loading
Loading