VComponents is a SwiftUI
package that contains 30+ customizable UI components.
Versions with different majors are not compatible.
Ver | Release Date | iOS | SwiftUI | VCore | Comment |
---|---|---|---|---|---|
3.0 | 2022 10 02 | 16.0 | 4.0 | 4.1.0 - 4.x.x | New SwiftUI API. API changes. |
2.0 | 2022 05 26 | 15.0 | 3.0 | 3.2.0 - 3.x.x | New SwiftUI API. API changes. SPM support. |
1.0 | 2021 02 07 | 14.0 | 2.0 | - | - |
Buttons. VPrimaryButton, VSecondaryButton, VRoundedButton, VRoundedLabeledButton, VPlainButton
State Pickers. VToggle, VCheckBox, VRadioButton
Item Pickers. VSegmentedPicker, VWheelPicker
Value Pickers. VStepper, VSlider, VRangeSlider
Inputs. VTextField, VTextView
Containers. VSheet, VDisclosureGroup
Lists. VList
Modals. VModal, VBottomSheet, VSideBar, VAlert, VConfirmationDialog, VMenu, VContextMenu
Messages. VToast
Indicators. VContinuousSpinner, VDashedSpinner, VProgressBar, VPageIndicator, VCompactPageIndicator, VAutomaticPageIndicator
Misc. VText, VWrappingMarquee, VBouncingMarquee
Components are not meant to be customized like you would a native SwiftUI
component.
Instead, UI model can be passed as parameter to initializers. This parameter has default value, and is not required every time you create a view.
UI Models are struct
s with default values. They break down into 5 models: Layout
, Colors
, Fonts
, Animations
, and Misc
.
For instance, changing foreground color of VSecondaryButton
can be done by passing an IU model.
Not Preferred:
var body: some View {
VSecondaryButton(
action: doSomething,
title: "Lorem ipsum"
)
.foregroundColor(.black)
}
Preferred:
let uiModel: VSecondaryButtonUIModel = {
var UIModel: VSecondaryButtonUIModel = .init()
uiModel.colors.textContent = .init(
enabled: .black,
pressed: .gray,
disabled: .gray
)
return uiModel
}()
var body: some View {
VSecondaryButton(
uiModel: uiModel,
action: doSomething,
title: "Lorem ipsum"
)
}
Alternately, you can create static instances of UI models for reusability.
extension VSecondaryButtonUIModel {
static let someUIModel: VSecondaryButtonUIModel = {
var uiModel: VSecondaryButtonModel = .init()
uiModel.colors.textContent = .init(
enabled: .black,
pressed: .gray,
disabled: .gray
)
return uiModel
}()
}
var body: some View {
VSecondaryButton(
uiModel: .someUIModel,
action: doSomething,
title: "Lorem ipsum"
)
}
Some components take type
as parameter. For instance, VPageIndicator
has three types: standard
, compact
, and automatic
var body: some View {
VStack(content: {
VPageIndicator(type: .standard(), total: 9, selectedIndex: 4)
VPageIndicator(type: .compact(), total: 99, selectedIndex: 4)
VPageIndicator(type: .automatic(), total: 99, selectedIndex: 4)
})
}
VComponents approaches animations as bound to components and their UI models, and not to state. Which means, that to modify a state of component with an animation, you need to pass a custom UI model.
Not Preferred:
@State var isOn: Bool = false
var body: some View {
VStack(content: {
VToggle(
isOn: $isOn,
title: "Lorem ipsum"
)
VSecondaryButton(
action: { withAnimation(nil, { isOn.toggle() }) },
title: "Toggle"
)
})
}
Preferred:
@State var isOn: Bool = false
let uiModel: VToggleUIModel = {
var uiModel: VToggleUIModel = .init()
uiModel.animations.stateChange = nil
return uiModel
}()
var body: some View {
VStack(content: {
VToggle(
uiModel: uiModel,
isOn: $isOn,
title: "Lorem ipsum"
)
VSecondaryButton(
action: { isOn.toggle() },
title: "Toggle"
)
})
}
First method is not only not preferred, but it will also not work. Despite specifying nil
to change state, VToggle
would still use its default animation.
Components manage state parameters internally, and animations used to change them externally do not have any effect.
Thought process behind his design choice was to centralize animations to UI model.
Components also prevent themselves from modifying external state with an animation.
Package contains demo app, that can be run to showcase all components.
Add https://github.com/VakhoKontridze/VComponents
as a Swift Package in Xcode and follow the instructions.
Major. Major changes, such as big overhauls
Minor. Minor changes, such as new component, types, or properties in UI models
Patch. Bug fixes and improvements
e-mail: [email protected]
link |
Stars: 231 |
Last commit: 2 days ago |
General
PresentationHost
is fixedforceDismiss(id:)
method in PresentationHost
is fixedpresentationHost(id:allowsHitTests:isPresented:content:)
method is added that replaces current PresentationHost
APIVRoundedLabeledButton
titleLabelLineType
from VRoundedLabeledButtonUIModel
is now utilized inside the buttonVRadioButton
VTextField
VTextFieldType
is renamed to ContentType
and is moved to VTextFieldUIModel
VTextView
TextLineLimitType
is removed from init
and can now be customized via textLineType
in VTextViewUIModel
VList
VListRowSeparatorType
is renamed to SeparatorType
and is moved to VListRowUIModel
VModal
VToast
VToastTextLineType
is renamed to TextLineType
and is moved to VToastUIModel
VSpinner
VSpinner
is split to VContinuousSpinner
and VDashedSpinner
VPageIndicator
VPageIndicator
is split to VPageIndicator
, VCompactPageIndicator
and VAutomaticPageIndicator
VMarquee
VMarquee
is split to VWrappingMarquee
and VBouncingMarquee
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics