Reputation: 279
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
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
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
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