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

SwiftUI实现滚动过文本后移至NavigationTitle的方法

SwiftUI实现Apple Music式滚动标题过渡效果(无需GeometryReader/ScrollViewReader)

当然可以实现,在iOS 17+版本的SwiftUI里,不用GeometryReader或ScrollViewReader也能轻松搞定——靠ScrollView新增的onScrollChange方法就能监听滚动偏移,配合导航栏自定义视图实现平滑过渡效果。

实现思路

核心逻辑很直接:

  • 页面内保留一个和导航栏标题完全一致的文本视图
  • 监听滚动偏移,当页面内的标题滚出导航栏区域时,让导航栏标题逐渐显示,同时页面内的标题逐渐隐藏
  • 通过调整透明度和位置偏移,实现无缝的过渡动画

完整代码示例

import SwiftUI

struct ScrollTitleTransitionView: View {
    // 模拟列表数据
    private let songs = (1...50).map { "第\($0)首歌" }
    // 记录滚动偏移量
    @State private var scrollOffset: CGFloat = 0
    // 统一的标题文本
    private let titleText = "我的最爱歌单"
    // 导航栏标题区域的基准高度(可根据实际需求调整)
    private let navBarHeight: CGFloat = 44
    
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(alignment: .leading, spacing: 16) {
                    // 页面内的标题,随滚动逐渐消失
                    Text(titleText)
                        .font(.largeTitle)
                        .fontWeight(.bold)
                        .padding()
                        // 根据滚动偏移调整透明度和位置
                        .opacity(max(0, 1 - (scrollOffset / navBarHeight)))
                        .offset(y: min(0, -scrollOffset))
                    
                    // 列表内容
                    ForEach(songs, id: \.self) { song in
                        Text(song)
                            .padding(.horizontal)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding(.vertical, 8)
                    }
                }
            }
            .scrollContentBackground(.hidden)
            // iOS17+新增API,直接监听滚动偏移
            .onScrollChange { context in
                scrollOffset = context.contentOffset.y
            }
            .navigationTitle("")
            .toolbar {
                // 导航栏标题,随滚动逐渐显示
                ToolbarItem(placement: .principal) {
                    Text(titleText)
                        .font(.title)
                        .fontWeight(.bold)
                        .opacity(max(0, (scrollOffset - navBarHeight) / navBarHeight))
                }
            }
        }
    }
}

#Preview {
    ScrollTitleTransitionView()
}

关键细节说明

  • onScrollChange:iOS17新增的原生API,无需额外布局读取器就能直接获取ScrollView的滚动偏移量
  • 透明度过渡:当滚动偏移小于导航栏高度时,页面内标题保持完全显示;超过阈值后,导航栏标题逐步显现,页面内标题逐步隐藏
  • 位置偏移:页面内标题随滚动向上偏移,避免和导航栏标题出现重叠,让过渡更自然流畅

这个实现和你参考的Apple Music滚动标题逻辑完全一致,代码简洁且未使用禁用的API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:05:10