View transitions animate a view entering or leaving the hierarchy. Content transitions (iOS 16) animate a change inside a view that stays put, such as a Text whose string, weight, or color changes. Without one, the change snaps with no visual effect.
Attach contentTransition Next to the Animation
Wrap the state change in withAnimation and pick a transition. .interpolate morphs between the states, right for font weight and color changes. .opacity cross-fades.
VStack {
Text(verbatim: "1000")
.fontWeight(flag ? .black : .light)
.foregroundColor(flag ? .yellow : .red)
}
.contentTransition(.interpolate)
.onTapGesture {
withAnimation(.default.speed(0.1)) {
flag.toggle()
}
}
numericText for Counters
.numericText() works only on numeric text. It understands which digits changed and animates only those, the rolling-counter effect.
Text(verbatim: number)
.font(.system(size: 36))
.contentTransition(.numericText())
.onTapGesture {
withAnimation(.default.speed(0.2)) {
number = "98"
}
}
The Transition Travels Through the Environment
contentTransition writes its value into the environment, so a custom text-drawing view can read \.contentTransition and honor the requested effect.
struct MySuperCustomTextView: View {
@Environment(\.contentTransition) private var transition
var body: some View {
switch transition {
case .opacity: drawWithOpacity()
case .interpolate: drawWithInterpolation()
default: draw()
}
}
}
Set \.contentTransitionAddsDrawingGroup to true to render the transition in a GPU-accelerated drawing group when the effect stutters.
.environment(\.contentTransitionAddsDrawingGroup, true)
.contentTransition(.interpolate)
Few views support content transitions so far; Text is the main one.