Home

Awesome

HypeUI

πŸš€ 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 😊

Awesome Swift

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

Contents

Requirements

Installation

Swift Package Manager

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"))
]

CocoaPod

The preferred installation method is with CocoaPods. Add the following to your Podfile:

pod 'HypeUI'

Supported Features

Supported Features
HStackβœ…
VStackβœ…
ZStackβœ…
Buttonβœ…
Textβœ…
Imageβœ…
ScrollViewβœ…
Behaviorβœ…
Spacerβœ…
LinearGradientβœ…
AlignmentViewβœ…
ViewBuildableβœ…
View Modifierβœ…
Text Modifierβœ…
Stack Modifierβœ…
ScrollView Modifierβœ…

<a name="view_modifier"></a>

View Modifier

nameDescription
setHContentHuggingAdjusts the priority for a view to resist growing beyond its intrinsic size horizontally.
setVContentHuggingAdjusts the priority for a view to resist growing beyond its intrinsic size vertically.
setHContentCompressionResistanceAdjusts the priority for a view to resist shrinking below its intrinsic size horizontally.
setVContentCompressionResistanceAdjusts the priority for a view to resist shrinking below its intrinsic size vertically.
makeRatioSets the aspect ratio constraint for the view's size.
cornerRadiusApplies a corner radius to the view to create rounded corners.
borderAdds a border with specified color and width to the view.
backgroundSets the background color of the view.
makeContentModeSets the content mode of the view.
framePositions the view within a specified frame size.
paddingAdds padding around specific edges of the view.
allowsHitTestingEnables or disables the view's interaction with touch events.
masksToBoundsClips the view's sublayers to its boundaries.
accessibilityIdentifierAssigns an identifier used to find this view in tests.
overlayPlaces specified views in front of the view.
backgroundLayers the views that you specify behind this view.
centerCenters the view within a new parent view.
tintApplies a tint color to the view.
opacitySets the transparency level of the view.
scaleEffectScales the view by specified factors along the x and y axes.
rotationEffectRotates the view by a specified angle around a given anchor point.

<a name="text_modifier"></a>

Text Modifier

nameDescription
fontSets the font of the text.
foregroundColorApplies a foreground color to the text.
textAlignedSets the alignment of the text within its container.
lineLimitSpecifies the maximum number of lines the text can span.
lineBreakModeDefines how text wraps when it reaches the edge of its container.
adjustFontSizeAdjusts the font size of the text to fit its width.
minimumScaleFactorSets the smallest multiplier for text size reduction to fit the width.
preferredMaxLayoutWidthSets the preferred maximum width for the Text object and enables method chaining.
baselineAdjustedApplies a baseline adjustment to the Text object and enables method chaining.

<a name="stack_modifier"></a>

Stack Modifier

nameDescription
distributedModify stack's distribution layout.

<a name="scrollview_modifier"></a>

ScrollView Modifier

nameDescription
bouncesModify scroll view bounces.
isPagingEnabledModify scroll view paging enabled.
isScrollEnabledModify scroll view enabled.

Usage

HStack

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

VStack(spacing: 8) {
    Text()
        .foregroundColor(UIColor.black)
        .font(UIFont.systemFont(ofSize: 14, weight: .regular))
    Spacer()
}

ZStack

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

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

Text("✨")
    .foregroundColor(UIColor.black)
    .font(UIFont.systemFont(ofSize: 14, weight: .regular))
    .textAligned(.center)
    .background(.white)
    .cornerRadius(16)

Image

Image(Resource.Profile.placeholderImage)
    .frame(width: 48, height: 48)
    .cornerRadius(24)

ScrollView

// 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 - It's seems like SwiftUI's @State using DynamicLinkable 😎

@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

Spacer()
    .frame(width: 10)
Spacer()
    .frame(height: 20)

LinearGradient

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")
            }
        }
    }
}

Main Contributors

cruz@hpcnt.com xeon@hpcnt.com owen.j@hpcnt.com dough@hpcnt.com

Dependencies