Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b2f83ec
added glass effect
efremidze Dec 26, 2025
5ac2d0c
Update VisualEffectView.swift
efremidze Dec 28, 2025
1cce2a4
Update VisualEffectView+SwiftUI.swift
efremidze Dec 28, 2025
7897323
Update VisualEffectView.swift
efremidze Dec 28, 2025
45e37b3
Update VisualEffectView.swift
efremidze Dec 28, 2025
fe5debd
Update VisualEffectView.swift
efremidze Dec 28, 2025
16f834d
Update VisualEffectView.swift
efremidze Dec 28, 2025
0b89eb7
Update VisualEffectView.swift
efremidze Dec 29, 2025
947cbbf
Update VisualEffectView.swift
efremidze Dec 29, 2025
d56258a
Update VisualEffectView.swift
efremidze Dec 29, 2025
9f15fef
Update UIViewEffectView+Helpers.swift
efremidze Dec 29, 2025
e8fbd1d
Update VisualEffectView+SwiftUI.swift
efremidze Dec 29, 2025
82cb57a
Update VisualEffectView+SwiftUI.swift
efremidze Dec 29, 2025
3b30202
Update VisualEffectView+SwiftUI.swift
efremidze Dec 29, 2025
738fa36
Update VisualEffectView.swift
efremidze Dec 29, 2025
5784874
Update VisualEffectView.swift
efremidze Dec 29, 2025
f5d3e8e
Update VisualEffectView.swift
efremidze Dec 29, 2025
89e34ad
Update README.md
efremidze Dec 29, 2025
a4ed2fa
Update VisualEffectView.podspec
efremidze Dec 29, 2025
64f0a89
Update CHANGELOG.md
efremidze Dec 29, 2025
65cfcd3
Update ContentView.swift
efremidze Dec 29, 2025
92ce8e2
Update VisualEffectView+SwiftUI.swift
efremidze Dec 29, 2025
21bb2eb
Update project.pbxproj
efremidze Dec 29, 2025
9f19500
Update VisualEffectView.swift
efremidze Dec 29, 2025
7605f3a
Update ContentView.swift
efremidze Dec 29, 2025
ffb6789
Update project.pbxproj
efremidze Dec 29, 2025
0de7578
Update VisualEffectView.swift
efremidze Dec 29, 2025
1316b5e
Revert "Update project.pbxproj"
efremidze Dec 29, 2025
469382e
Update ContentView.swift
efremidze Dec 29, 2025
1b5655e
updated project
efremidze Dec 29, 2025
29a6630
Update Package.swift
efremidze Dec 29, 2025
bcf5406
Update VisualEffectView.podspec
efremidze Dec 29, 2025
f17e05c
Update VisualEffectView.swift
efremidze Dec 29, 2025
d32bc43
Update VisualEffectView.swift
efremidze Dec 29, 2025
f82ad7a
Update VisualEffectView.swift
efremidze Dec 29, 2025
c1bf56e
Update ContentView.swift
efremidze Dec 29, 2025
a6ed031
Update ContentView.swift
efremidze Dec 29, 2025
ac6b9fa
Update ContentView.swift
efremidze Dec 29, 2025
bf8bf07
Update README.md
efremidze Dec 29, 2025
9685e29
Update VisualEffectView.podspec
efremidze Dec 29, 2025
99bea4b
Merge branch 'glass' of https://github.com/efremidze/VisualEffectView…
efremidze Dec 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change log

## [Version 6.0.0](https://github.com/efremidze/VisualEffectView/releases/tag/6.0.0)

- Added iOS 26+ glass effect support with automatic fallback
- Added style-based API with `.systemBlur`, `.customBlur`, and `.glass` options

## [Version 5.0.8](https://github.com/efremidze/VisualEffectView/releases/tag/5.0.8)

- Readded saturation
Expand Down
220 changes: 195 additions & 25 deletions Example/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,215 @@ import SwiftUI
import VisualEffectView

struct ContentView: View {
@State private var blurRadius: CGFloat = 0
typealias VisualEffectStyle = VisualEffectView.VisualEffectStyle
@State private var blurRadius: CGFloat = 18
@State private var colorTintAlpha: CGFloat = 0.5
@State private var saturation: CGFloat = 1.0

var body: some View {
ZStack(alignment: .bottom) {
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 16) {
ForEach(Color.colors, id: \.self) { color in
ZStack {
Image(systemName: "swift")
.resizable()
.scaledToFit()
.frame(width: 50, height: 100)
.foregroundStyle(.black)
ZStack {
// Animated background
AnimatedBackground()
.ignoresSafeArea()

ScrollView {
VStack(spacing: 32) {
// Header
VStack(spacing: 8) {
Text("VisualEffectView")
.font(.largeTitle)
.fontWeight(.bold)
Text("Dynamic blur effects with style-based API")
.font(.subheadline)
.foregroundStyle(.secondary)
}
.padding(.top, 20)

// Custom Blur Section
VStack(alignment: .leading, spacing: 16) {
Text("Custom Blur")
.font(.title2)
.fontWeight(.semibold)
.padding(.horizontal, 4)

// Custom blur controls
VStack(alignment: .leading, spacing: 16) {
VStack(spacing: 12) {
VStack(alignment: .leading, spacing: 4) {
HStack {
Text("Blur Radius")
Spacer()
Text("\(Int(blurRadius))")
.foregroundStyle(.secondary)
}
Slider(value: $blurRadius, in: 0...30)
}

VStack(alignment: .leading, spacing: 4) {
HStack {
Text("Tint Alpha")
Spacer()
Text(String(format: "%.2f", colorTintAlpha))
.foregroundStyle(.secondary)
}
Slider(value: $colorTintAlpha, in: 0...1)
}

VStack(alignment: .leading, spacing: 4) {
HStack {
Text("Saturation")
Spacer()
Text(String(format: "%.2f", saturation))
.foregroundStyle(.secondary)
}
Slider(value: $saturation, in: 0...3)
}
}
}
.padding()
.background {
RoundedRectangle(cornerRadius: 16)
.fill(.ultraThinMaterial)
}

// Custom blur demo
DemoCard(
title: "Custom Blur",
style: .customBlur,
colorTint: .white,
colorTintAlpha: colorTintAlpha,
blurRadius: blurRadius,
saturation: saturation
)

// Color tint examples
VStack(alignment: .leading, spacing: 12) {
Text("Color Tint Examples")
.font(.headline)
.padding(.horizontal, 4)

LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 12) {
ForEach([
("Red", Color.red),
("Blue", Color.blue),
("Green", Color.green),
("Purple", Color.purple)
], id: \.0) { name, color in
DemoCard(
title: name,
style: .customBlur,
colorTint: color,
colorTintAlpha: colorTintAlpha,
blurRadius: blurRadius,
saturation: saturation,
height: 120
)
}
}
}
}

// Glass Effect Section
VStack(alignment: .leading, spacing: 16) {
Text("Glass Effect")
.font(.title2)
.fontWeight(.semibold)
.padding(.horizontal, 4)

VisualEffect(
colorTint: color,
colorTintAlpha: 0.5,
blurRadius: blurRadius
DemoCard(
title: "Glass Regular",
style: .glass(.regular)
)
}
}
.padding()
}
}
}
}

// MARK: - Demo Card

struct DemoCard: View {
let title: String
let style: VisualEffectView.VisualEffectStyle
var colorTint: Color?
var colorTintAlpha: CGFloat = 0
var blurRadius: CGFloat = 0
var saturation: CGFloat = 1
var height: CGFloat = 200

private var isCustomBlur: Bool {
if case .customBlur = style { return true }
return false
}

var body: some View {
ZStack {
if isCustomBlur {
VisualEffect(
colorTint: colorTint,
colorTintAlpha: colorTintAlpha,
blurRadius: blurRadius,
saturation: saturation
)
} else {
VisualEffect(style: style)
}
}
.frame(height: height)
.clipShape(RoundedRectangle(cornerRadius: 20))
.overlay {
VStack(spacing: 8) {
Text(title)
.font(.headline)
if isCustomBlur {
Text("Blur: \(Int(blurRadius))")
.font(.caption)
.foregroundStyle(.secondary)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
}
}
}

// MARK: - Animated Background

struct AnimatedBackground: View {
var body: some View {
TimelineView(.animation) { timeline in
let time = timeline.date.timeIntervalSinceReferenceDate

VStack {
Slider(value: $blurRadius, in: 0...20)
ZStack {
LinearGradient(
colors: [.blue, .purple, .pink, .orange],
startPoint: .topLeading,
endPoint: .bottomTrailing
)

Text("Slide to blur")
.font(.caption)
.foregroundStyle(.secondary)
// Animated shapes
ForEach(0..<3, id: \.self) { index in
Circle()
.fill(
LinearGradient(
colors: [.white.opacity(0.2), .clear],
startPoint: .top,
endPoint: .bottom
)
)
.frame(width: 200 + Double(index) * 100)
.offset(
x: cos(time / 5 + Double(index) * 2) * 100,
y: sin(time / 5 + Double(index) * 2) * 100
)
}
}
.padding(.horizontal, 32)
.padding(.bottom, 32)
}
}
}

private extension Color {
static let colors = [red, orange, yellow, green, teal, blue, purple, pink]
}
// MARK: - Preview

#Preview {
ContentView()
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(name: "VisualEffectView")
],
swiftLanguageVersions: [.v5]
swiftLanguageVersions: [.v5, .version("6")]
)
77 changes: 55 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![Swift](https://img.shields.io/badge/Swift-5.9+-orange.svg)](https://swift.org)
[![License](https://img.shields.io/github/license/efremidze/VisualEffectView.svg)](https://github.com/efremidze/VisualEffectView/blob/master/LICENSE)

**VisualEffectView** is a blur effect library with tint color support. This library uses the [UIVisualEffectView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/) to generate the blur.
**VisualEffectView** is a dynamic blur effect library with tint color support and iOS 26+ glass effects. This library uses [UIVisualEffectView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/) to generate the blur.

<img src="/Images/demo.gif" width="250" />

Expand All @@ -23,25 +23,53 @@ $ pod try VisualEffectView

## Usage

Add an instance of VisualEffectView to your view.
### UIKit

```swift
import VisualEffectView

let visualEffectView = VisualEffectView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))

// Configure the view with tint color, blur radius, etc
visualEffectView.colorTint = .redColor()
// Customize the blur
visualEffectView.colorTint = .red
visualEffectView.colorTintAlpha = 0.2
visualEffectView.blurRadius = 10
visualEffectView.scale = 1

addSubview(visualEffectView)
```

Depending on the desired effect, the effect may affect content layered behind the view or content added to the visual effect view’s contentView. After you add the visual effect view to the view hierarchy, add any subviews to the contentView property of the visual effect view. Do not add subviews directly to the visual effect view itself. Refer to the [UIVisualEffectView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/) for more info.
You can also use different styles:

For more examples, take a look at the example project.
```swift
// System blur
visualEffectView.style = .systemBlur(.dark)

// Glass effect (iOS 26+)
visualEffectView.style = .glass(.regular)

// Custom blur (default)
visualEffectView.style = .customBlur
```

### SwiftUI

```swift
import VisualEffectView

struct ContentView: View {
var body: some View {
VisualEffect(colorTint: .white, colorTintAlpha: 0.5, blurRadius: 18, scale: 1)
}
}
```

Or use the style-based API:

```swift
VisualEffect(style: .glass(.regular))
VisualEffect(style: .systemBlur(.dark))
```

### Customization

Expand All @@ -53,28 +81,23 @@ var scale: CGFloat // scale factor. default is 1
var saturation: CGFloat // saturation factor. default is 1
```

If you want `colorTintAlpha` to be different from `0`, make sure you always set it right after setting the `colorTint` or it may not be applied as expected.
You also have to make sure you don't set `colorTintAlpha` if `colorTint` is `nil`.
**Note:** Custom blur properties only work when `style` is `.customBlur`.

### Storyboard Support

Works great with storyboards and xibs.
If you want `colorTintAlpha` to be different from `0`, make sure you always set it right after setting the `colorTint` or it may not be applied as expected. Don't set `colorTintAlpha` if `colorTint` is `nil`.

### SwiftUI Support
### Content View

VisualEffectView supports SwiftUI.
Add subviews to the `contentView` property, not directly to the visual effect view:

```swift
import VisualEffectView

struct ContentView: View {
var body: some View {
VisualEffect(colorTint: .white, colorTintAlpha: 0.5, blurRadius: 10, scale: 1)
}
}
visualEffectView.contentView.addSubview(label)
```

Make sure that `colorTintAlpha` is not set when `colorTint` is `nil`.
Refer to the [UIVisualEffectView](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/) documentation for more info.

### Storyboard Support

Works great with storyboards and xibs.

## Installation

Expand All @@ -91,8 +114,16 @@ To install with [Carthage](https://github.com/Carthage/Carthage), simply add thi
github "efremidze/VisualEffectView"
```

### Swift Package Manager
Add VisualEffectView as a dependency in your `Package.swift` file:
```swift
dependencies: [
.package(url: "https://github.com/efremidze/VisualEffectView.git", from: "6.0.0")
]
```

### Manually
1. Download and drop ```VisualEffectView.swift``` in your project.
1. Download and drop the source files in your project.
2. Congratulations!

## Communication
Expand All @@ -105,6 +136,8 @@ github "efremidze/VisualEffectView"

VisualEffectView utilizes a private UIKit API to do its magic. Use caution, submitting this code to the App Store adds the risk of being rejected!

The `.systemBlur()` and `.glass()` styles use only public APIs and are safe for App Store submission.

## Credits

https://github.com/collinhundley/APCustomBlurView
Expand Down
2 changes: 1 addition & 1 deletion Sources/VisualEffectView/UIViewEffectView+Helpers.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// UIViewEffectViewiOS14.swift
// UIVisualEffectView+Helpers.swift
// VisualEffectView
//
// Created by Lasha Efremidze on 9/14/20.
Expand Down
Loading