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

SwiftUI中Refreshable Indicator视图出现时自动显示的问题

问题:Refreshable Indicator在视图加载时自动显示(仅iOS 16.1物理设备+inline导航栏)

现象与环境

  • 视图出现时,Refreshable Indicator自动显示,无需下拉列表;上滑列表后指示器隐藏,后续下拉刷新功能可正常执行(显示、操作、隐藏)
  • 仅在iPhone 13 Pro Max(iOS 16.1)物理设备上复现,同版本模拟器无此问题
  • 触发条件:仅当navigationBarTitleDisplayMode设置为.inline时出现,使用默认.large时无此问题
  • 已尝试无效操作:调整.refreshable修饰符顺序、修改.listStyle

相关代码

struct OrdersView: View {
    @EnvironmentObject private var tabBarStateManager: TabBarStateManager
    @EnvironmentObject private var profileViewModel: ProfileViewModel
    
    @StateObject private var ordersViewModel: OrdersViewModel = OrdersViewModel()
    
    @Environment(\.dismiss) private var dismiss: DismissAction
    
    var body: some View {
        List {
            ForEach(ordersViewModel.datesForOrdersViewListSections, id: \.self) { stringDate in
                Section {
                    ForEach(ordersViewModel.getOrdersFor(date: stringDate), id: \.self) { order in
                        NavigationLink(destination: OrderDetailsView(order: order,
                                                                     orderProductsList: ordersViewModel.getOrderProductsFor(order: order))
                                                                                            .environmentObject(ordersViewModel)) {
                            VStack(alignment: .leading, spacing: 20) {
                                HStack(spacing: 10) {
                                    Text(order.id)
                                        .font(.ssCallout)
                                    Spacer()
                                    Text(Date.getDayAndMonthFrom(date: order.orderDate))
                                        .font(.ssTitle3)
                                        .foregroundColor(.accentColor)
                                }
                                
                                Text("\(order.totalCost, specifier: \"%.2f\")")
                                    .font(.ssTitle3)
                                    .foregroundColor(.accentColor)
                                
                                VStack(alignment: .leading) {
                                    HStack {
                                        Text(TexterifyManager.localisedString(key: .ordersView(.products)))
                                            .font(.ssCallout)
                                        Text("\(ordersViewModel.getOrderProductsFor(order: order).count)")
                                            .font(.ssTitle3)
                                            .foregroundColor(.accentColor)
                                    }
                                        
                                    HStack {
                                        Text(TexterifyManager.localisedString(key: .ordersView(.orderStatus)))
                                            .font(.ssCallout)
                                        Text(order.status.rawValue)
                                            .font(.ssTitle3)
                                            .foregroundColor(.accentColor)
                                    }
                                }
                            }
                            .padding(.vertical)
                        }
                    }
                } header: {
                    Text(stringDate)
                        .font(.ssTitle1)
                        .foregroundColor(.accentColor)
                }
            }
        }
        .listStyle(.grouped)
        .refreshable {
            profileViewModel.fetchUserOrders {
                ordersViewModel.userOrders = profileViewModel.userOrders
            }
        }
        .navigationTitle(TexterifyManager.localisedString(key: .ordersView(.navigationTitle)))
        .navigationBarTitleDisplayMode(.inline)
        .navigationBarBackButtonHidden(true)
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Button {
                    dismiss()
                } label: {
                    Image(systemName: "arrow.backward.circle.fill")
                        .resizable()
                        .frame(width: 30, height: 30)
                        .foregroundColor(.accentColor)
                }
            }
        }
        .onAppear {
            ordersViewModel.userOrders = profileViewModel.userOrders
        }
    }
}

解决方案建议

1. 手动重置滚动位置(快速临时修复)

在onAppear中延迟执行滚动到顶部的操作,强制隐藏自动弹出的指示器:

.onAppear {
    ordersViewModel.userOrders = profileViewModel.userOrders
    // 延迟0.1秒执行,确保视图已完成布局
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        UIScrollView.appearance().setContentOffset(.zero, animated: false)
    }
}

如果不想全局修改UIScrollView,也可以用ScrollViewReader控制当前List的滚动:

// 先在结构体里添加状态变量
@State private var scrollProxy: ScrollViewProxy?

// 给List添加scrollViewReader修饰
List {
    // ...原有列表内容
}
.scrollViewReader { proxy in
    scrollProxy = proxy
}

// 修改onAppear
.onAppear {
    ordersViewModel.userOrders = profileViewModel.userOrders
    DispatchQueue.main.async {
        withAnimation(.easeInOut(duration: 0.1)) {
            scrollProxy?.scrollTo(nil, anchor: .top)
        }
    }
}

2. 调整.refreshable的修饰位置

将.refreshable从List移到外层的Navigation容器上(适用于iOS 16+的NavigationStack):

NavigationStack {
    List {
        // ...原有列表内容
    }
    .listStyle(.grouped)
    .navigationTitle(TexterifyManager.localisedString(key: .ordersView(.navigationTitle)))
    .navigationBarTitleDisplayMode(.inline)
    // ...其他导航栏相关修饰
}
.refreshable {
    profileViewModel.fetchUserOrders {
        ordersViewModel.userOrders = profileViewModel.userOrders
    }
}

3. 升级iOS系统版本

该问题属于iOS 16.1的已知兼容性bug,升级到iOS 16.2及以上版本后,苹果官方已修复类似的导航栏与下拉刷新冲突问题,建议优先测试新版本系统是否解决问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:50:39