在iOS中,如何完美复现原生iMessage的联系人/个人资料切换动画?

人工智能 2026-07-09

我正在开发一款iOS即时通讯应用,正在尝试复现Apple Messages应用在对话顶部点击联系对象/个人资料时所使用的精确交互与动画效果。

在此处输入图片描述

问题在于Claude/Codex/AI工具总是在生成一些“相似”的东西,但并非真正的iOS原生效果。

我想知道:

  1. 这个转场/交互模式在技术上叫什么名字?
  2. 我应该给Claude/Codex发送什么精确的提示,使其理解我想要近乎像素级完美、原生iMessage风格的转场?

理想情况下,我希望:

  • 精确的动画架构
  • 正确的术语
  • 以及一个能够让AI生成真实效果而非通用动画的提示结构。

并且那个新屏幕也应该具备透明/玻璃效果。

解决方案

这看起来像一个 zoom 导航过渡,最终进入全屏覆盖。

一个放大导航过渡是通过将 .navigationTransition.matchedTransitionSource 结合使用来实现的。我不知道你会怎么让Claude/Codex为你生成这个,但下面有一个示例,演示了它的工作:

struct ContentView: View {
    @State private var isShowingDetail = false
    @Namespace private var ns

    var body: some View {
        VStack {
            Button {
                isShowingDetail = true
            } label: {
                VStack {
                    Image(systemName: "person.crop.circle.fill")
                        .font(.largeTitle)
                        .imageScale(.large)
                        .foregroundStyle(.indigo)
                    Text("Name")
                }
            }
            .buttonStyle(.plain)
            .matchedTransitionSource(id: 0, in: ns)
            Text("Other content")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
        .fullScreenCover(isPresented: $isShowingDetail) {
            DetailView()
                .navigationTransition(.zoom(sourceID: 0, in: ns))
        }
    }
}

struct DetailView: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            Text("Detail view")
                .toolbar {
                    ToolbarItem(placement: .topBarLeading) {
                        Button("Back", systemImage: "chevron.backward") {
                            dismiss()
                        }
                    }
                }
        }
    }
}

动画


你还提到过:

那个新屏幕也应该具备透明/玻璃效果

我不确定Messages应用是否有玻璃效果,还是在覆盖层使用了材质背景,或者两者都可能。无论如何,你都可以通过对全屏覆盖应用 .presentationBackground(.clear),并在详情视图的内容背后设置所需的背景来实现这个效果。类似如下:

DetailView()
    .presentationBackground(.clear)
    .navigationTransition(.zoom(sourceID: 0, in: ns))
// DetailView

NavigationStack {
    // ...
}
.background {
    Rectangle()
        .fill(.regularMaterial)
        .glassEffect(.clear, in: .containerRelative)
        .ignoresSafeArea()
}

不幸的是,背景似乎只有在放大过渡完成后才会显示,这对用户体验并不理想。帖子 当Glass Element是 navigationTransition的来源时的奇怪动画 也与此问题相关。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章