A lightweight, high-performance iOS library that provides animated border-tracing loading indicators and progress bars for any view shape — rectangles, rounded rectangles, circles, capsules, or custom paths.
On iOS 26+, LuminaKit automatically leverages Apple's Liquid Glass material for a premium, system-native look. On iOS 18–25, it falls back to a polished glassmorphic glow effect.
| SwiftUI Demo | UIKit Demo |
|---|---|
![]() |
![]() |
- Multiple Animation Styles: Choose between
.bubble(classic moving bubble),.ring(lineWidth:)(continuous 360° rotating arc), and.pulse(breathing glow border). - Determinate Progress Indicators: Border progress animation for SwiftUI (
.luminaProgress) and UIKit (showLuminaProgress), complete with automatic zero-value hiding. - Advanced Color Customization (
LuminaColorMode&LuminaColors):auto: Automatically adapts to system Appearance (Light/Dark mode) with charcoal light mode defaults for maximum contrast.light/dark: Explicit theme locking.custom(LuminaColors): Full control over primary color, stroke glow, shadow, and track colors.adaptive(light:dark:): Set distinct custom color palettes for light and dark modes.
- Enhanced UIKit Performance: Zero-jitter animation loop using
CADisplayLink+ seamless stroke wrap-around on circular and rectangular paths.
- iOS 18.0+
- Swift 6.0+
- Xcode 16.0+
Add LuminaKit to your Package.swift:
dependencies: [
.package(url: "https://github.com/iarafathsn/LuminaKit.git", from: "2.0.0")
]Or in Xcode: File → Add Package Dependencies → search https://github.com/iarafathsn/LuminaKit.git
Add the following to your Podfile:
pod 'LuminaLoaderKit', '~> 2.0'Then run:
pod installAdd the following to your Cartfile:
github "iarafathsn/LuminaKit" ~> 2.0
Then run:
carthage update --use-xcframeworksimport SwiftUI
import LuminaKit
struct ContentView: View {
@State private var isLoading = false
var body: some View {
VStack(spacing: 20) {
// 1. Standard Bubble Loader (Default)
Button("Bubble Loader") { isLoading.toggle() }
.padding()
.luminaLoader(isAnimating: $isLoading)
// 2. Rotating Ring Loader
Button("Ring Loader") { isLoading.toggle() }
.padding()
.clipShape(RoundedRectangle(cornerRadius: 12))
.luminaLoader(
isAnimating: $isLoading,
shape: RoundedRectangle(cornerRadius: 12),
style: .ring(lineWidth: 3)
)
// 3. Breathing Pulse Loader
Button("Pulse Loader") { isLoading.toggle() }
.padding()
.clipShape(Capsule())
.luminaLoader(
isAnimating: $isLoading,
shape: Capsule(),
style: .pulse
)
}
}
}struct ProgressViewExample: View {
@State private var progress: CGFloat = 0.45
var body: some View {
Button("Upload File") { }
.padding()
.clipShape(RoundedRectangle(cornerRadius: 10))
.luminaProgress(
value: $progress,
shape: RoundedRectangle(cornerRadius: 10)
)
}
}// Single custom color scheme
let customTheme = LuminaColors(
primary: .indigo,
glow: .indigo.opacity(0.5)
)
Button("Custom Theme") { }
.luminaLoader(
isAnimating: $isLoading,
colorMode: .custom(customTheme)
)
// Adaptive Light & Dark mode colors
let adaptiveMode = LuminaColorMode.adaptive(
light: LuminaColors(primary: .blue),
dark: LuminaColors(primary: .cyan)
)
Button("Adaptive Theme") { }
.luminaLoader(
isAnimating: $isLoading,
colorMode: adaptiveMode
)import UIKit
import LuminaKit
// Show loader on any UIView or UIButton
button.showLuminaLoader(style: .bubble)
// Ring style with custom speed
button.showLuminaLoader(style: .ring(lineWidth: 4), speed: 0.8)
// Hide loader
button.hideLuminaLoader()
// Object-based instantiation
let loaderView = LuminaLoaderUIView(
configuration: LuminaConfiguration(style: .ring(lineWidth: 3))
)
myView.addSubview(loaderView)
loaderView.frame = myView.bounds
loaderView.startAnimating()// Show progress indicator (0.0 to 1.0)
cardView.showLuminaProgress(value: 0.25)
// Update progress during task
cardView.updateLuminaProgress(value: 0.85)
// Hide progress when complete
cardView.hideLuminaProgress().bubble: Glowing bubble travelling along the border..ring(lineWidth: CGFloat): Smooth rotating arc along the border..pulse: Border glow pulsing in and out.
.auto: Adapts to Light (charcoal/dark contrast) and Dark (glowing cyan/white) appearance..light: Enforces light mode color scheme..dark: Enforces dark mode color scheme..custom(LuminaColors): Uses custom colors..adaptive(light: LuminaColors, dark: LuminaColors): Different custom colors for light/dark modes.
primary: Main accent color.glow: Color for stroke glow effect.shadow: Color for bubble shadow.progressTrack: Color for underlying progress track path.
LuminaKit is available under the MIT License. See LICENSE for details.

