Apple Intelligence Glow Effect

repository·main·Indexed 43 days ago

https://github.com/jacobamobin/appleintelligencegloweffect

A SwiftUI-based implementation of the Apple Intelligence glow effect that mimics Apple's design language without using Metal shaders. It provides platform-specific implementations for iOS, iPadOS, and WatchOS, including performance-optimized versions like IOS_LowPowerMode.swift and WatchOS_WithFreeze.swift. The library includes components such as GlowEffect, Effect, and EffectNoBlur to customize animation timing, gradient colors, and blur layers.

Tokens
2.5K
Snippets
7
Records
11
Agent score
6%

What's inside Apple Intelligence Glow Effect

  1. Customize gradient colors

    main

    To match your app's theme, override the generateGradientStops() function. This function returns an array of Gradient.Stop objects. Ensure the array is sorted by location to maintain valid gradient rendering.

    static func generateGradientStops() -> [Gradient.Stop] {
        [
            Gradient.Stop(color: Color(hex: "BC82F3"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "F5B9EA"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "8D9FFF"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "AA6EEE"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "FF6778"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "FFBA71"), location: Double.random(in: 0...1)),
            Gradient.Stop(color: Color(hex: "C686FF"), location: Double.random(in: 0...1))
        ].sorted { $0.location < $1.location }
    }
  2. Install the Apple Intelligence Glow Effect

    main

    To use this effect in your SwiftUI project, follow these steps:

    1. Copy the platform-specific file that matches your target device (e.g., WatchOS.swift, IOS.swift, or iPadOS.swift) into your Xcode project.
    2. Import the file into your SwiftUI view.
    3. Implement the effect using the provided components like GlowEffect, Effect, or EffectNoBlur.
  3. Customize layers with Effect and EffectNoBlur

    main

    For more granular control, you can stack multiple layers using EffectNoBlur (for sharp edges) and Effect (for blurred overlays). This allows you to create depth by varying the width and blur parameters.

    ZStack {
        // Base layer with no blur
        EffectNoBlur(gradientStops: gradientStops, width: 5)
            .onAppear {
                Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { _ in
                    withAnimation(.easeInOut(duration: 0.5)) {
                        gradientStops = GlowEffect.generateGradientStops()
                    }
                }
            }
        
        // Blurred overlay layer
        Effect(gradientStops: gradientStops, width: 7, blur: 4)
            .onAppear {
                Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { _ in
                    withAnimation(.easeInOut(duration: 0.6)) {
                        gradientStops = GlowEffect.generateGradientStops()
                    }
                }
            }
    }
  4. Customize animation timing and speed

    main

    You can control the fluidity and speed of the glow by adjusting the Timer interval and the withAnimation duration. A shorter interval results in faster color shifts.

    Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { _ in
        withAnimation(.easeInOut(duration: 0.5)) {
            gradientStops = GlowEffect.generateGradientStops()
        }
    }
  5. Optimize rendering performance for glow effects

    main

    When implementing or customizing glow effects, use these SwiftUI modifiers to reduce CPU/GPU overhead caused by heavy blur operations:

    1. .drawingGroup(): Use this to composite all layers into a single render pass, which is highly effective for complex animations.
    2. .compositingGroup(): Use this to optimize individual blur rendering within a group.
    3. Reduce Blur Layers: In low-power scenarios, reduce the number of layers in the ZStack. Fewer layers result in significantly lower CPU usage.
    4. Adjust Blur Radius: Lowering the blur radius values reduces the amount of GPU work required.
    // Example of rendering optimization
    ZStack {
        // ... glow layers ...
    }
    .drawingGroup() // Composite layers into a single render pass
    .compositingGroup() // Optimize individual blur rendering
  6. Choose the appropriate glow effect variant for your platform

    main

    To balance visual quality and performance, select the implementation file based on your target device and performance requirements:

    iOS Platform

    • High-End Devices (iPhone 12+): Use IOS.swift for full visual quality (4 layers, 0.5s update interval).
    • Older Devices or Battery Saving: Use IOS_LowPowerMode.swift for reduced CPU usage (2 layers, 1.0s update interval).
    • Minimal Impact: Use TypeToSiri.swift for a simple gradient cycling animation suitable for all devices (5-10% CPU usage).

    WatchOS Platform

    • Newer Watches (Series 10, Ultra 1/2): Use WatchOS.swift.
    • All WatchOS 11 Devices: Use WatchOS_WIthFreeze.swift. This is the recommended choice as it supports automatic corner radius detection and includes a freeze capability to stop animations entirely (0% CPU when frozen).
  7. Monitor and test CPU usage of glow effects

    main

    If you experience high CPU usage, use the following methods to profile the effect:

    Using Xcode Instruments

    1. Go to Product > Profile (Cmd+I).
    2. Select Time Profiler.
    3. Run your app and monitor CPU usage in real-time.

    Using Xcode Debug Navigator

    1. Run the app on a device or simulator.
    2. Open the Debug Navigator (Cmd+7).
    3. Observe the CPU gauge while the effect is visible.
  8. Implement the basic Glow Effect

    main

    The simplest way to implement the effect is to use the GlowEffect component. You must manage a @State variable for gradientStops and initialize it using GlowEffect.generateGradientStops() when the view appears.

    struct ContentView: View {
        @State private var gradientStops: [Gradient.Stop] = []
        
        var body: some View {
            ZStack {
                // Your content here
                GlowEffect(gradientStops: gradientStops)
                    .onAppear {
                        gradientStops = GlowEffect.generateGradientStops()
                    }
            }
        }
    }
  9. Implement device-based auto-selection for glow effects

    main

    You can create an adaptive view that automatically selects the most performant glow effect based on the device's power state or hardware capabilities.

    struct AdaptiveGlowEffect: View {
        var body: some View {
            if ProcessInfo.processInfo.isLowPowerModeEnabled {
                GlowEffectLowPower()
            } else if UIDevice.current.userInterfaceIdiom == .phone {
                // Check device model for older iPhones
                GlowEffectLowPower()
            } else {
                GlowEffect()
            }
        }
    }
  10. Implement efficient timer-based animations with Combine

    main

    To avoid timer leaks and redundant state updates, use a single shared timer managed via the Combine framework and ensure proper cleanup using .onDisappear.

    @State private var timer: AnyCancellable?
    
    // Setup timer
    timer = Timer.publish(every: 0.5, on: .main, in: .common)
        .autoconnect()
        .sink { _ in
            withAnimation(.easeInOut(duration: 1.0)) {
                gradientStops = GlowEffect.generateGradientStops()
            }
        }
    
    // Cleanup to prevent leaks
    .onDisappear {
        timer?.cancel()
        timer = nil
    }
  11. Choose the right implementation for your platform

    main

    The repository provides optimized files for different use cases and hardware capabilities:

    iOS

    • TypeToSiri.Swift: Optimized for the Siri-style typing effect (5-10% CPU).
    • IOS.swift: Standard version for iPhone 12+ (40-60% CPU).
    • IOS_LowPowerMode.swift: Ultra-performance version for older devices or battery saving (20-30% CPU).

    WatchOS

    • WatchOS.swift: Standard optimized version (Series 10, Ultra 1/2 compatible).
    • WatchOS_WithFreeze.swift: Enhanced version with freeze capability and full WatchOS 11 compatibility (all watch sizes).

    iPadOS

    • iPadOS.swift: Optimized for larger displays with increased corner radius (65pt) and adjusted blur/line widths.