π 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]