Search code examples
iosswiftswiftuitoolbar

ToolbarContent: add a .disabled(Bool) method


I've created a custom ToolbarContent for common buttons, such as Save, Edit, Cancel, etc...

For example:


import SwiftUI

public struct SaveToolbarItem: ToolbarContent {
    private let placement: ToolbarItemPlacement
    private let action: () -> Void

    public init(placement: ToolbarItemPlacement = .confirmationAction,
                action: @escaping () -> Void = {}) {
        self.placement = placement
        self.action = action
    }

    public var body: some ToolbarContent {
        ToolbarItem(placement: placement) {
            Button(
                "Save"
            ) {
                action()
            }
        }
    }
}

At call site:

        .toolbar {            
            SaveToolbarItem() {
                 // some code for the Action
                presentationMode.wrappedValue.dismiss()
            }
            .disabled(true) // Value of type 'SaveToolbarItem' has no member 'disabled'
        }

However, I'm getting the following error while trying to use isDisabled method:

Value of type 'SaveToolbarItem' has no member 'disabled'

How can I mitigate this error? E.g. maybe define disabled only on my custom types of ToolbarContent?


Solution

  • You need to place it inside, like

    public var body: some ToolbarContent {
        ToolbarItem(placement: placement) {
            Button(
                "Save"
            ) {
                action()
            }
            .disabled(true)     // << here !!
        }
    }
    

    *of course parameter for disabled is expected to be passed in.

    Updated: Here is possible approach with built-in disabled modifier.

    Tested with Xcode 13.2 / iOS 15.2

    demo

    public struct SaveToolbarItem: ToolbarContent {
        private let placement: ToolbarItemPlacement
        private let action: () -> Void
    
        private var enabled = true
    
        public init(placement: ToolbarItemPlacement = .confirmationAction,
                    action: @escaping () -> Void = {}) {
            self.placement = placement
            self.action = action
        }
    
        public var body: some ToolbarContent {
            ToolbarItem(placement: placement) {
                Button(
                    "Save"
                ) {
                    action()
                }
                .disabled(!enabled)
            }
        }
    
        func disabled(_ flag: Bool) -> Self {
            var newItem = self
            newItem.enabled = !flag
            return newItem
        }
    }