Basic Usage
How to set up appearance and manage behavior of the components.
Appearance
All components in the library have view models that should be used to configure their appearance. These models are shared between SwiftUI and UIKit components. For example, an input field can be configured as follows:
let inputFieldVM = InputFieldVM {
$0.title = "Email"
$0.placeholder = "Enter your email"
$0.isRequired = true
}
All view models in ComponentsKit do not have memberwise initializers. Instead, they conform to the ComponentVM
protocol, which defines an initializer that modifies default values:
/// Initializes a new instance by applying a transformation closure to the default values.
///
/// - Parameter transform: A closure that defines the transformation.
init(_ transform: (_ value: inout Self) -> Void)
This approach has two main benefits:
- It allows you to set parameters in any order, making the initializers easier to use.
- Future changes can be made without breaking your code, as it simplifies deprecation.
Behavior
To control the behavior in SwiftUI, you should use bindings:
struct App: View {
@State var email = ""
@FocusState var isEmailFieldFocused: Bool
var body: some View {
VStack {
SUInputField(
text: $email,
isFocused: $isEmailFieldFocused,
model: inputFieldVM
)
.onChange(of: self.email) { newValue in
// Track changes in the inputted text
print("Email: \(newValue)")
}
SUButton(
model: .init {
$0.title = isEmailFieldFocused
? "Hide Keyboard"
: "Show Keyboard"
$0.isFullWidth = true
},
action: {
// Control the focus (hide / show the keyboard)
self.isEmailFieldFocused.toggle()
}
)
}
.padding(.horizontal)
}
}
To control the behavior in UIKit, you should use the components' public variables:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UKButton(model: .init {
$0.title = "Show Keyboard"
})
let inputField = UKInputField(
model: inputFieldVM,
onValueChange: { text in
// Track changes in the inputted text
print("Email: \(text)")
}
)
button.action = { [weak inputField, weak button] in
// Control the focus (hide / show the keyboard)
guard let inputField, let button else { return }
if inputField.isFirstResponder {
inputField.resignFirstResponder()
button.model.title = "Show Keyboard"
} else {
inputField.becomeFirstResponder()
button.model.title = "Hide Keyboard"
}
}
view.addSubview(inputField)
view.addSubview(button)
inputField.horizontally(16)
inputField.centerVertically(offset: -50)
button.below(inputField, padding: 10)
button.horizontally(16)
}
}