BLACK FRIDAY SALE: Save 50% on all my Swift books and bundles! >>

Day 67: Disabling slider problem.

Forums > 100 Days of SwiftUI

Hello. I have just finished day 67 and solved challenges for instaFilter. I have added 4 slider for different filters to my view. I want sliders to be active if currentFilter have parameter for this slider parameter. For example if I choose Crystallize, only "radius" slider should be active. Although I can not change Intensity parameter and Text color become gray as expected when I switched to crystallize, slider color still looks active (but I can not change the value as should be). Do you have any idea, why the slider looks active although it is inactive?

import PhotosUI
import CoreImage
import CoreImage.CIFilterBuiltins
import SwiftUI

struct ContentView: View {
    @State private var image: Image?
    @State private var filterIntensity = 0.5
    @State private var filterRadius = 0.5
    @State private var filterScale = 0.5
    @State private var filterSaturationAmount = 0.0
    @State private var showingImagePicker = false
    @State private var inputImage: UIImage?
    @State private var processedImage: UIImage?
    @State private var currentFilter: CIFilter = CIFilter.sepiaTone()
    let context = CIContext()

    @State private var showingFilterSheet = false

    var body: some View {
        NavigationView {
            VStack {
                ZStack {

                    Text("Tap to select a picture")

                .onTapGesture {
                    showingImagePicker = true
                HStack {
                    VStack {
                            .foregroundColor(!currentFilter.inputKeys.contains(kCIInputIntensityKey) ? .gray: .black)
                        Slider(value: $filterIntensity)
                            .onChange(of: filterIntensity) { _ in
                            .foregroundColor(!currentFilter.inputKeys.contains(kCIInputRadiusKey) ? .gray: .black)
                        Slider(value: $filterRadius)
                            .onChange(of: filterRadius) { _ in
                            .foregroundColor(!currentFilter.inputKeys.contains(kCIInputScaleKey) ? .gray: .black)
                        Slider(value: $filterScale)
                            .onChange(of: filterScale) { _ in
                        Text("Saturation Amount")
                            .foregroundColor(!currentFilter.inputKeys.contains(kCIInputAmountKey) ? .gray: .black)
                        Slider(value: $filterSaturationAmount, in: -1.0...1.0)
                            .onChange(of: filterSaturationAmount) { _ in


                HStack {
                    Button("Change Filter") {
                        showingFilterSheet = true

                        Button("Save", action: save)
                        .disabled((inputImage == nil))
                    // save the picture
        .padding([.horizontal, .bottom])
        .sheet(isPresented: $showingImagePicker) {
            ImagePicker(image: $inputImage)

        .confirmationDialog("Select a filter", isPresented: $showingFilterSheet) {
                Group {
                    Button("Comic Effect") {setFilter(CIFilter.comicEffect()) }
                    //comic use no parameter
                    Button("Crystallize") { setFilter(CIFilter.crystallize()) }
                    Button("Edges") { setFilter(CIFilter.edges()) }
                    Button("Dither") {setFilter(CIFilter.dither()) }
                    //dither use intensity
                    Button("Gaussian Blur") { setFilter(CIFilter.gaussianBlur()) }
                Group {
                    Button("Pixellate") { setFilter(CIFilter.pixellate()) }
                    Button("Sepia Tone") { setFilter(CIFilter.sepiaTone()) }
                    Button("Unsharp Mask") { setFilter(CIFilter.unsharpMask()) }
                    Button("Vibrance") {setFilter(CIFilter.vibrance()) }
                    //vibrance use amount parameter
                    Button("Vignette") { setFilter(CIFilter.vignette()) }
                    Button("Cancel", role: .cancel) { }

        .onChange(of: inputImage) { _ in loadImage()}
    func loadImage() {
        guard let inputImage = inputImage else { return }

        let beginImage = CIImage(image: inputImage)
        currentFilter.setValue(beginImage, forKey: kCIInputImageKey)

    func save() {
        guard let processedImage = processedImage else { return }

        let imageSaver = ImageSaver()

        imageSaver.successHandler = {

        imageSaver.errorHandler = {
            print("Oops: \($0.localizedDescription)")

        imageSaver.writeToPhotoAlbum(image: processedImage)

    func applyProcessing() {
        let inputKeys = currentFilter.inputKeys

        if inputKeys.contains(kCIInputIntensityKey) { currentFilter.setValue(filterIntensity, forKey: kCIInputIntensityKey) }
        if inputKeys.contains(kCIInputRadiusKey) { currentFilter.setValue(filterRadius * 200, forKey: kCIInputRadiusKey) }
        if inputKeys.contains(kCIInputScaleKey) { currentFilter.setValue(filterScale * 10, forKey: kCIInputScaleKey) }
        if inputKeys.contains(kCIInputAmountKey) { currentFilter.setValue(filterSaturationAmount , forKey: kCIInputAmountKey) }

        guard let outputImage = currentFilter.outputImage else { return }

        if let cgimg = context.createCGImage(outputImage, from: outputImage.extent) {
            let uiImage = UIImage(cgImage: cgimg)
            image = Image(uiImage: uiImage)
            processedImage = uiImage

    func setFilter(_ filter: CIFilter) {
        currentFilter = filter

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {


Posted on Paul's birthday in 2022. Happy birthday, sensei!

Dre has a slider question:

Why does the slider look active although it is disabled?

You posted a lot of code! Much of your code has nothing to do with your problem. I think this is part of what clouds new developers' minds. Their quest is to get their application working. But all the excess code fogs the essence of the problem.

Loading images? kCIInputRadiusKey? ImageSaver? None of this is essential to your issue. Focus!

Instead of solving your solution's goals, take a step back to the playground, and just pick ONE piece of equipment and have fun!

Every playground has a slide! Let's have fun with that for a while. Focus on the slide (Slider!).

struct SliderTestView: View {
    @State private var filterIntensity = 20.0  // set the initial slider value
    @State private var filterIsActive  = true
    // encapsulate your intentions as computed variables where possible
    var filterColor: Color { filterIsActive ? .accentColor : .gray.opacity(0.3) }
    var intensityDisplayString: String { String(format: "%.1f", filterIntensity) }

    var body: some View {
        VStack(spacing: 20) {
            Toggle("Intensity", isOn: $filterIsActive) // Turn the filter ON or OFF
                .frame(width: 150)
            // These react when filterIsActive variable changes
            Group {
                Image(systemName: "globe")
                Text( "Intensity: " + intensityDisplayString)  // simplify!
                Slider(value: $filterIntensity, in: 0...50)
                // slider color does not use foregroundColor, instead use accentColor
                    .accentColor(filterColor)   // Slider color
                    .disabled(!filterIsActive)  // disable slider
            .foregroundColor( filterColor )     // both image and text

// Boilerplate
struct SliderTestView_Previews: PreviewProvider {
    static var previews: some View { SliderTestView() }

Please return here and share with us what you learned. Also would like to know how you implemented your improved solution.

Nick at Swiftful Thinking has some additional thoughts on Sliders(). See -> Swiftful Thinking: Sliders


Hacking with Swift is sponsored by Guardsquare

SPONSORED AppSweep by Guardsquare helps developers automate the mobile app security testing process with fast, free scans. By using AppSweep’s actionable recommendations, developers can improve the security posture of their apps in accordance with security standards like OWASP.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.