免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

swiftui-ui-patterns - scroll-reveal

swiftui-ui-patterns - scroll-reveal 滚动揭示详情界面意图当详情界面的主表面在前、次级内容在其后方且你希望用户通过滚动或滑动而不是点击单独按钮来揭示次级层时使用此模式。典型适用场景揭示操作或元数据的媒体详情界面过渡到结构化详情的地图、卡片或画布带第二个操作或洞察页的全屏查看器核心模式将交互构建为带有两个分区的分页垂直ScrollView一个尺寸与视口一致的主分区其下方的次级分区从垂直内容偏移量推导归一化的progress值并从这个单一值驱动所有视觉变化。除非仅靠滚动无法表达该交互否则避免把揭示当作一套独立的手势系统。最小结构privateenumDetailSection:Hashable{caseprimarycasesecondary}structDetailSurface:View{StateprivatevarrevealProgress:CGFloat0StateprivatevarsecondaryHeight:CGFloat1varbody:someView{GeometryReader{geometryinScrollViewReader{proxyinScrollView(.vertical,showsIndicators:false){VStack(spacing:0){PrimaryContent(progress:revealProgress).frame(height:geometry.size.height).id(DetailSection.primary)SecondaryContent(progress:revealProgress).id(DetailSection.secondary).onGeometryChange(for:CGFloat.self){geoingeo.size.height}action:{newHeightinsecondaryHeightmax(newHeight,1)}}.scrollTargetLayout()}.scrollTargetBehavior(.paging).onScrollGeometryChange(for:CGFloat.self,of:{scrollinscroll.contentOffset.yscroll.contentInsets.top}){_,offsetinrevealProgress(offset/secondaryHeight).clamped(to:0...1)}.safeAreaInset(edge:.bottom){ChevronAffordance(progress:revealProgress){withAnimation(.smooth){lettarget:DetailSectionrevealProgress0.5?.secondary:.primary proxy.scrollTo(target,anchor:.top)}}}}}}}应保留的设计选择当交互应像状态之间分页时让主分区恰好等于视口大小。从真实的滚动偏移量计算progress而不是从isExpanded、isShowingSecondary、isSnapped等重复的布尔值。用progress驱动offset、opacity、blur、scaleEffect和工具栏状态使整个表面保持同步。对来自主内容点击或 chevron 提示符的编程式吸附使用ScrollViewReader。当需要确定的区域状态用于触觉反馈、提示条关闭、分析或无障碍播报时使用onScrollTargetVisibilityChange。变形一个共享控件如果一个控件看起来从主表面移动到次级内容中不要渲染两个完整可见的副本。而是在主区域暴露一个源锚点在次级区域暴露一个目标锚点渲染一个用progress插值位置和大小的覆盖层Color.clear.anchorPreference(key:ControlAnchorKey.self,value:.bounds){anchorin[source:anchor]}Color.clear.anchorPreference(key:ControlAnchorKey.self,value:.bounds){anchorin[destination:anchor]}.overlayPreferenceValue(ControlAnchorKey.self){anchorsinMorphingControlOverlay(anchors:anchors,progress:revealProgress)}这能保持运动连贯并避免重复点击目标引发的 bug。触觉反馈与提示符揭示开始时使用轻阈值触觉反馈接近确定状态时使用更强的触觉反馈。当progress接近零时保持像 chevron 或胶囊这样的可见提示符。随着次级分区变为活动状态翻转、淡出或模糊提示符。交互防护当冲突的模式如捏合缩放、裁剪或全屏媒体操作激活时禁用垂直滚动。禁用那些一旦次级内容被揭示就应消失的覆盖层的命中测试。避免同轴嵌套滚动视图除非内层视图在揭示期间实际上是静态的或被禁用。陷阱不要硬编码 progress 除数。测量次级分区高度或其他真实的揭示距离。不要为同一属性混用多个动画来源。如果progress驱动它就让其他动画远离该属性。除非其他 API 需要不要存储isSecondaryVisible这样的派生状态。优先从progress或可见滚动目标推导它。测量高度时当心布局反馈循环。钳制零值并且只在测量高度实际变化时更新。具体示例Pool iOS 图块详情揭示/Users/dimillian/Documents/Dev/Pool/pool-ios/Pool/Sources/Features/Tile/Detail/TileDetailView.swift次级内容锚点示例/Users/dimillian/Documents/Dev/Pool/pool-ios/Pool/Sources/Features/Tile/Detail/TileDetailIntentListView.swift
返回列表