π HypeUI is a implementation of Apple's SwiftUI DSL style based on UIKit Want to enjoy SwiftUI syntax with UIKit? It's time to use HypeUI π
Why to use HypeUI? | |
---|---|
π± | Support iOS 12 |
β¨ | HypeUI is compatible with UIKit based project using SwiftUI style syntax |
πββοΈ | Reduce UI & Autolayout codes more than 30% |
β³οΈ | Provide UI binding extension with RxSwift and RxCocoa |
π¦ | Easy to use! |
Improve readability and intuitiveness of complex layouts | |
π€© | Have a blast |
β· | Customize reusable component, design system |
βοΈ | Test with accessibility Identifier |
- iOS 12.0
- XCode 13.0
- Swift 5.0
Swift Package Manager is a tool for managing the distribution of Swift code. Itβs integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
Xcode 13 is required to build HypeUI using Swift Package Manager.
To integrate HypeUI into your Xcode project using Swift Package Manager, add it to the dependencies value of your Package.swift
:
dependencies: [
.package(url: "https://github.com/hyperconnect/HypeUI", .upToNextMajor(from: "0.3.0"))
]
The preferred installation method is with CocoaPods. Add the following to your Podfile
:
pod 'HypeUI'
Supported Features | |
---|---|
HStack | β |
VStack | β |
ZStack | β |
Button | β |
Text | β |
Image | β |
ScrollView | β |
Behavior | β |
Spacer | β |
LinearGradient | β |
AlignmentView | β |
ViewBuildable | β |
View Modifier | β |
Text Modifier | β |
Stack Modifier | β |
ScrollView Modifier | β |
name | Description |
---|---|
setHContentHugging | Adjusts the priority for a view to resist growing beyond its intrinsic size horizontally. |
setVContentHugging | Adjusts the priority for a view to resist growing beyond its intrinsic size vertically. |
setHContentCompressionResistance | Adjusts the priority for a view to resist shrinking below its intrinsic size horizontally. |
setVContentCompressionResistance | Adjusts the priority for a view to resist shrinking below its intrinsic size vertically. |
makeRatio | Sets the aspect ratio constraint for the view's size. |
cornerRadius | Applies a corner radius to the view to create rounded corners. |
border | Adds a border with specified color and width to the view. |
background | Sets the background color of the view. |
makeContentMode | Sets the content mode of the view. |
frame | Positions the view within a specified frame size. |
padding | Adds padding around specific edges of the view. |
allowsHitTesting | Enables or disables the view's interaction with touch events. |
masksToBounds | Clips the view's sublayers to its boundaries. |
accessibilityIdentifier | Assigns an identifier used to find this view in tests. |
overlay | Places specified views in front of the view. |
background | Layers the views that you specify behind this view. |
center | Centers the view within a new parent view. |
tint | Applies a tint color to the view. |
opacity | Sets the transparency level of the view. |
scaleEffect | Scales the view by specified factors along the x and y axes. |
rotationEffect | Rotates the view by a specified angle around a given anchor point. |
name | Description |
---|---|
font | Sets the font of the text. |
foregroundColor | Applies a foreground color to the text. |
textAligned | Sets the alignment of the text within its container. |
lineLimit | Specifies the maximum number of lines the text can span. |
lineBreakMode | Defines how text wraps when it reaches the edge of its container. |
adjustFontSize | Adjusts the font size of the text to fit its width. |
minimumScaleFactor | Sets the smallest multiplier for text size reduction to fit the width. |
preferredMaxLayoutWidth | Sets the preferred maximum width for the Text object and enables method chaining. |
baselineAdjusted | Applies a baseline adjustment to the Text object and enables method chaining. |
name | Description |
---|---|
distributed | Modify stack's distribution layout. |
name | Description |
---|---|
bounces | Modify scroll view bounces. |
isPagingEnabled | Modify scroll view paging enabled. |
isScrollEnabled | Modify scroll view enabled. |
HStack(alinement: .center, spacing: 4) {
Image(Asset.icStar.image)
.frame(width: 12, height: 12)
Text()
.foregroundColor(UIColor.black)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
Spacer()
}
VStack(spacing: 8) {
Text()
.foregroundColor(UIColor.black)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
Spacer()
}
ZStack {
HStack(alinement: .center, spacing: 4) {
Image(Asset.icStar.image)
.frame(width: 12, height: 12)
Text()
.foregroundColor(UIColor.black)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
Spacer()
}
VStack {
Text()
.foregroundColor(UIColor.black)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
Spacer()
}
}
Button(action: { // DO SOMETHING ex) reactor action, closure }) {
HStack(alignment: .center, spacing: 5.0) {
Image("cart")
.padding(.leading, 10.0)
Text("Add to Cart")
.foregroundColor(.black)
.padding(.all, 10.0)
}
}
.background(Color.gray)
.cornerRadius(5)
Text("β¨")
.foregroundColor(UIColor.black)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
.textAligned(.center)
.background(.white)
.cornerRadius(16)
Image(Resource.Profile.placeholderImage)
.frame(width: 48, height: 48)
.cornerRadius(24)
// MARK: Example
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .fill) {
Image(image: Asset.imgPopupPrivateCall.image)
.makeRatio(0.46106)
Spacer()
.frame(height: 24)
VStack {
viewModel.messages.map { message in
HStack(alignment: .top, spacing: 8) {
Text("β’")
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
.foregroundColor(.Palette.gray04)
.frame(width: 6)
Text(message)
.font(UIFont.systemFont(ofSize: 14, weight: .regular))
.foregroundColor(.Palette.gray04)
.lineLimit(2)
.lineBreakMode(.byCharWrapping)
Spacer()
.frame(width: 5)
}
.padding(.vertical, 8)
}
}
Spacer()
.frame(height: 16)
}
}
@Behavior var isLive: Bool = false
@Behavior var username: String? = nil
@Behavior var profileImageURL: URL? = nil
// MARK Example
final class SearchHostHistoryViewCell: UICollectionViewCell {
@Behavior var isLive: Bool = false
@Behavior var username: String? = nil
@Behavior var profileImageURL: URL? = nil
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubviewWithFit(
ZStack {
VStack(alignment: .center, spacing: 8) {
Image(Resource.Profile.placeholderImage)
.linked($profileImageURL.flatMapLatest { $0?.getImage(failover: Resource.Profile.placeholderImage) ?? .just(Resource.Profile.placeholderImage) }, keyPath: \.image)
.makeContentMode(.scaleAspectFill)
.frame(width: 48, height: 48)
.cornerRadius(24)
.background(.Palette.gray05)
Text("")
.linked($username, keyPath: \.text)
.textAligned(.center)
.foregroundColor(.darkModeSupporting(.Palette.gray01, .Palette.dkGray01))
.font(UIFont.systemFont(ofSize: 10, weight: .regular))
.frame(height: 12)
}.padding(UIEdgeInsets(top: 12, left: 0, bottom: 4, right: 0))
VStack(alignment: .center) {
Spacer()
Text("LIVE")
.foregroundColor(.Palette.white)
.font(UIFont.systemFont(ofSize: 8, weight: .bold))
.padding(UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4))
.background(.Palette.red)
.cornerRadius(4)
.linked($isLive.not(), keyPath: \.isHidden)
Spacer()
.frame(height: 20)
}
}
)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Spacer()
.frame(width: 10)
Spacer()
.frame(height: 20)
ProfileView()
.background(
LinearGradient(
gradient: Gradient(
stops: [
Stop(color: UIColor.black, location: 1.0),
Stop(color: UIColor.black, location: 0.2),
Stop(color: UIColor.black, location: 0.0)
]),
startPoint: .top,
endPoint: .bottom
)
)
ViewBuildable - Customize UI, Make reusable component and Design System by confirming ViewBuildable protocol.
struct ProfileView: ViewBuildable {
@Behavior var country: String
@Behavior var name: String
func build() -> UIView {
VStack {
HStack(alignment: .center, spacing: 12) {
Text("")
.linked($country, keyPath: \.text)
.font(UIFont.systemFont(ofSize: 20, weight: .regular))
.accessibilityIdentifier("country")
Text("")
.linked($name, keyPath: \.text)
.font(UIFont.systemFont(ofSize: 20, weight: .regular))
.accessibilityIdentifier("name")
}
}
}
}
[email protected] [email protected] [email protected] [email protected]