Reputation: 8193
I think that the View.disabled(_:)
modifier changes the .foregroundColor
of a View
(besides enabling / disabling interactions with it). Could the color change be animated?
I know it's pretty easy to animate say .opacity
changes with implicit animations (e.g.: .animation(.default)
). However the same won't work with .disabled
.
Please consider the following code:
import SwiftUI
struct SomeButton: View {
@State var isDisabled = false
@State var isHidden = false
var body: some View {
VStack(spacing: 30) {
Spacer()
Button(action: {}) {
Image(systemName: "pencil.circle.fill")
.resizable()
}
.frame(width: 80, height: 80)
.disabled(isDisabled) // 👈🏻 Will not animate at all.
.opacity(isHidden ? 0 : 1) // 👈🏻 Will animate just fine.
.animation(.default) // 👈🏻 Set to use implicit animations.
VStack(spacing: 10) {
Button(action: {
self.isHidden.toggle()
}) {
Text("Hide")
}
Button(action: {
self.isDisabled.toggle()
}) {
Text("Disable")
}
}
Spacer()
}
}
}
// MARK: - Preview
#if DEBUG
struct SomeButton_Previews: PreviewProvider {
static var previews: some View {
SomeButton()
}
}
#endif
This produces the following result, which presents a smooth opacity transition:
... on the other hand the enabled / disabled color transition is binary. It doesn't look that good.
My current workaround is to change the opacity of a view based on its enabled/disabled state. So for example if a view is disabled, the opacity is 0.6. If enabled, the opacity goes back to 1.0.
But it feels wrong. There must be another way.
Upvotes: 3
Views: 1649
Reputation: 257789
The possible solution can be to combine with .colorMultipy
, of course the disabled color should be experimentally fit, but this gives common effect animatable
.disabled(isDisabled)
.colorMultiply(isDisabled ? // 👈🏻 animatable
Color.gray /* to be selected to fit*/ : .white)
.animation(.default, value: isDisabled)
Upvotes: 3