You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI 4/iOS 16中Asymmetric Transition行为是否发生变化?

iOS 16中Asymmetric Transition与分页TabView联动异常修复

问题描述

在iOS 15中,基于分页TabView实现的联动不对称过渡动画运行正常:滑动切换页面时,顶部文本视图的动画方向能完全匹配页面滑动方向。但升级到iOS 16后,滑动几页再切换方向,会出现顶部视图的移除和插入动画来自同一边缘的异常,过渡效果不符合预期。

问题原因

iOS 16中SwiftUI的状态更新通知机制和动画触发逻辑发生了变化。原代码通过@Published属性的willSet观察者更新pageDirection,但在iOS 16中,selectedPage的@Published通知可能先于pageDirection的更新被SwiftUI捕获,导致过渡动画计算时使用的是旧的方向值,最终出现动画异常。

解决方案

通过自定义绑定同步更新选中页和滑动方向,确保状态变化与动画触发在同一上下文内完成,让SwiftUI能准确获取最新的方向值来计算过渡动画。

修改后代码示例

import SwiftUI

class SharedStore: ObservableObject {
    @Published var selectedPage: Int = 0
    var pageDirection: UIPageViewController.NavigationDirection = .forward
}

struct ContentView: View {
    @StateObject var sharedStore = SharedStore()
    
    var body: some View {
        VStack {
            Text("Page \(sharedStore.selectedPage)")
                .id(sharedStore.selectedPage)
                .frame(maxWidth: UIScreen.main.bounds.width)
                .transition(
                    .asymmetric(
                        insertion: .move(edge: sharedStore.pageDirection == .forward ? .trailing : .leading),
                        removal: .move(edge: sharedStore.pageDirection == .forward ? .leading : .trailing)
                    )
                )
            
            // 使用自定义绑定替代直接绑定@Published属性
            TabView(selection: Binding(
                get: { sharedStore.selectedPage },
                set: { newValue in
                    withAnimation(.easeInOut) {
                        // 先更新方向,再更新选中页
                        sharedStore.pageDirection = newValue > sharedStore.selectedPage ? .forward : .reverse
                        sharedStore.selectedPage = newValue
                    }
                }
            )) {
                ForEach(0..<10, id:\.self) { index in
                    Text("Hello \(index)")
                }
            }
            .tabViewStyle(.page)
        }
        .padding()
    }
}

方案说明

  1. 移除SharedStore中selectedPage的willSet观察者,将方向判断逻辑移到自定义绑定的set方法中。
  2. 使用withAnimation包裹状态更新操作,确保pageDirection和selectedPage的变化被SwiftUI同时捕获,动画上下文能获取到最新的方向参数,从而生成正确的不对称过渡效果。

内容的提问来源于stack exchange,提问作者skegget

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:45:47