user1151874
user1151874

Reputation: 279

SwiftUI disable drag function

I have a simple view which contains a group of Buttons which allow drag feature depends on condition. How can i disable .onDrag based on the condition? The .disabled only disable click function.

    ScrollView
    {
        ForEach(animals, id: \.id)
        {
            animal in
            Button(action:{})
            {
               Text(animal.name)
            }
                .disabled(!animal.isEnable)
                .onDrag
                {
                    let provider = NSItemProvider(object: animal.name as NSString )
                    provider.suggestedName = animal.name
                    return provider
                }
          }
    }

Upvotes: 8

Views: 7571

Answers (3)

miff
miff

Reputation: 342

Disabled usually won't work.

Create an extension for a View and put if

extension View {
    @ViewBuilder func `if`<Content: View>(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View {
        if condition() {
            transform(self)
        } else {
            self
        }
    }
}

and use like this:

Button(//) {
//
}
.if(animal.isEnable, transform: { view in
    view
       .draggable()
       // or .onDrag...
}

Upvotes: 2

mert
mert

Reputation: 1098

.disable kills the interaction with the view therefore no dragging so it does what you need

you can check the documentation

A view that controls whether users can interact with this view. https://developer.apple.com/documentation/swiftui/list/disabled(_:)

I think there might be a small mistake here, better to be sure isEnable param is correctly sent.

.disabled(!animal.isEnable)

Upvotes: 0

Asperi
Asperi

Reputation: 257533

Here is a solution with helper modifier. Tested with Xcode 11.4.

// @available(iOS 13.4, *) - needed for iOS
struct Draggable: ViewModifier {
    let condition: Bool
    let data: () -> NSItemProvider

    @ViewBuilder
    func body(content: Content) -> some View {
        if condition {
            content.onDrag(data)
        } else {
            content
        }
    }
}

// @available(iOS 13.4, *) - needed for iOS
extension View {
    public func drag(if condition: Bool, data: @escaping () -> NSItemProvider) -> some View {
        self.modifier(Draggable(condition: condition, data: data))
    }
}

and updated your code would be

ForEach(animals, id: \.id)
{
    animal in
    Button(action:{})
    {
        Text(animal.name)
    }
    .disabled(!animal.isEnable)
    .drag(if: animal.isEnable) {     // << here !!
        let provider = NSItemProvider(object: animal.name as NSString )
        provider.suggestedName = animal.name
        return provider
    }
}

Upvotes: 13

Related Questions