news 2026/10/15 18:05:42

Onboard 框架示例画廊全解析:从 Gemr、Tripnary 真实案例到源码级引导页搭建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Onboard 框架示例画廊全解析:从 Gemr、Tripnary 真实案例到源码级引导页搭建
  • 移动开发
  • UI组件

【免费下载链接】Onboard

An iOS framework to easily create a beautiful and engaging onboarding experience with only a few lines of code.

项目地址:https://gitcode.com/gh_mirrors/on/Onboard
点击查看免费下载

examples.md 是 Onboard 框架的"示例画廊",集中展示了作者自制的演示动图,以及 Gemr、Tripnary、Almanac 等真实使用 Onboard 的 App 引导流程。本文以该画廊为骨架,逐一拆解每个示例对应的实现手法,并结合仓库源码(Source/目录)与 Demo 工程(Demo/Demo Files/AppDelegate.m)深入讲解:如何用两个核心类拼装引导页、如何定制间距与字体、如何实现遮罩/模糊/淡入淡出、如何控制自动导航与跳过。读完本文,你将能把画廊中的每一种视觉效果落地为自己的引导页。

一、示例画廊:Onboard 引导页能长什么样

examples.md 开篇即说明:画廊中既有作者自己"为了好玩"做的示例,也有使用 Onboard 的开发者提交的真实 App 案例。这意味着 Onboard 的引导页设计自由度非常高——同一个框架既可以驱动官方 demo,也可以承载商业产品的个性化品牌设计。

1.1 官方示例动图

画廊顶部的waves.gif是作者制作的官方 demo 之一(README 顶部还展示了 city、almanac、solar、tripnary 四组动图)。这类动图演示了 Onboard 的完整交互闭环:内容页随滑动切换、图标/标题/正文/按钮依次呈现、背景保持静止或播放视频。它的价值在于证明——通过几个 API 调用即可获得"开箱即用"的成品级引导体验。

1.2 社区真实 App:Gemr

Gemr 是画廊中第一个第三方应用案例,配套展示了 gemr.gif、gemr1.PNG、gemr2.PNG、gemr3.PNG 四张截图。从截图可以看到,它在 Onboard 的内容页结构(图标 + 标题 + 正文 + 按钮)之上做了自己的品牌化定制,这正是第 5 节要讲的自定义能力发挥作用的地方。

1.3 社区真实 App:Tripnary

Tripnary 是画廊中截图最丰富的案例,包含 tripnary.gif 与 tripnary1.PNG 至 tripnary5.PNG 共六张图,完整覆盖了多页引导的每一屏。它可以作为"多内容页 + 自定义主题色 + 按钮交互"的参考模板——你可以用第 3 节的方法为它复刻同样的页面序列。

1.4 Almanac(coming soon)

画廊中还收录了 Almanac 的预览(almanac.gif、almanac1.png、almanac2.png、almanac3.png),文档中将其标注为 "coming soon",即当时尚未上线、先放出设计预览的应用。这提示我们:Onboard 的引导页可以在产品研发早期就先行设计并评审,动图/截图本身就是很好的交互原型材料。

1.5 More Samples:Solar / Space / Purple 系列

画廊末尾的 "More Samples" 是作者制作的三组主题化示例,也是探索 Onboard 表现力的最佳素材:

  • Solar 系列:以 solar.gif 为主,搭配 solar1.png、solar2.png、solar3.png,适合观察暖色调内容页如何与背景协调。
  • Space 系列:space1.png 至 space4.png 四屏,演示同一引导流程中每页使用不同图标与文案时的视觉连续性。
  • Purple 系列:purple1.png 至 purple4.png,展示紫色系配色的统一质感。

这些示例之所以风格各异,是因为 Onboard 将"每页的内容"与"整体的背景/流程"解耦,任何一页都可以替换图标、调整文字、改字体颜色(第 5 节详解),因此换一套素材就是一套新皮肤。

1.6 如何提交你的作品

examples.md 在画廊末尾邀请使用 Onboard 的开发者提交自己的作品。也就是说,如果你用 Onboard 做出了漂亮的引导页,同样可以被收录进官方示例画廊。

二、示例背后的架构:两个核心类

画廊里所有示例的实现都建立在两个类之上,这正是 Onboard 的架构核心(接口定义见 Source/OnboardingViewController.h 与 Source/OnboardingContentViewController.h):

  • OnboardingViewController:引导流程的容器。负责静态背景图片/背景视频、UIPageViewController分页、页码指示器(pageControl)和跳过按钮(skipButton)。
  • OnboardingContentViewController:单个内容页。每个页面由四部分组成——图标(iconImageView)、标题(titleLabel)、正文(bodyLabel)、动作按钮(actionButton)。

README 对这套结构的概括是:一次引导体验 = 背景 + 内容页集合。背景承载"氛围",内容页承载"信息与操作",两者通过UIPageViewController的横向滚动串联。

从源码看,OnboardingViewController实现了UIPageViewControllerDataSource/Delegate与UIScrollViewDelegate(Source/OnboardingViewController.h),并持有currentPage/upcomingPage两个状态(Source/OnboardingViewController.m),用于在页面切换时计算过渡动画。测试用例testContentViewControllers(Demo/Demo Files/OnboardTests/OnboardTests.m)验证了初始化时传入的内容 VC 数组会被完整保存到viewControllers属性。

三、从零搭建一个引导流程:README 用法详解

画廊中的每个示例,落到代码上都只有几个步骤。README 给出了最小可运行路径。

3.1 安装

CocoaPods 方式,在Podfile中加入并执行pod install:

pod 'Onboard'

也可以使用 Carthage,或者直接把 Source/ 下的四个文件拖进工程手动集成。podspec(Onboard.podspec)声明了版本2.3.3、iOS 部署目标8.0、MIT 许可,源文件为Source/OnboardingViewController.{h,m}与Source/OnboardingContentViewController.{h,m}。

3.2 创建内容页

用OnboardingContentViewController创建页面,传入标题、正文、图片、按钮文字,并在 action block 中处理按钮点击(比如请求定位权限、注册推送、连接社交账号或结束引导)。不需要按钮时,把buttonText和 action 都传nil即可。

Objective-C:

OnboardingContentViewController *firstPage = [OnboardingContentViewController contentWithTitle:@"Page Title" body:@"Page body goes here." image:[UIImage imageNamed:@"icon"] buttonText:@"Text For Button" action:^{ // do something here when users press the button, like ask for location services permissions, register for push notifications, connect to social media, or finish the onboarding process }];

Swift:

let firstPage = OnboardingContentViewController(title: "Page Title", body: "Page body goes here.", image: UIImage(named: "icon"), buttonText: "Text For Button") { () -> Void in // do something here when users press the button, like ask for location services permissions, register for push notifications, connect to social media, or finish the onboarding process }

除了contentWithTitle:body:image:buttonText:action:,OnboardingContentViewController.h还提供了带actionBlock(回调会拿到OnboardingViewController实例)、以及内容页内嵌视频(contentWithTitle:body:videoURL:buttonText:action:)等变体,Demo 工程第 4.3 节就用到了视频变体。

3.3 创建引导控制器并展示

创建OnboardingViewController,提供背景图片或本地视频 URL,并传入刚才创建的内容页数组,然后以模态方式呈现:

Objective-C:

// 图片背景 OnboardingViewController *onboardingVC = [OnboardingViewController onboardWithBackgroundImage:[UIImage imageNamed:@"background"] contents:@[firstPage, secondPage, thirdPage]]; // 视频背景 NSBundle *bundle = [NSBundle mainBundle]; NSString *moviePath = [bundle pathForResource:@"yourVid" ofType:@"mp4"]; NSURL *movieURL = [NSURL fileURLWithPath:moviePath]; OnboardingViewController *onboardingVC = [OnboardingViewController onboardWithBackgroundVideoURL:movieURL contents:@[firstPage, secondPage, thirdPage]];

Swift:

// 图片背景 let onboardingVC = OnboardingViewController(backgroundImage: UIImage(named: "background"), contents: [firstPage, secondPage, thirdPage]) // 视频背景 let bundle = NSBundle.mainBundle() let moviePath = bundle.pathForResource("yourVid", ofType: "mp4") let movieURL = NSURL(fileURLWithPath: moviePath!) let onboardingVC = OnboardingViewController(backgroundVideoURL: movieUrl, contents: [firstPage, secondPage, thirdPage])

背景视频播放由AVPlayer驱动,控制器在viewWillAppear开始播放、并在 App 回到前台时自动恢复(Source/OnboardingViewController.m 与handleAppEnteredForeground)。如果不需要页面上的交互按钮,内容页的buttonText/action 传nil即可得到纯展示型页面——Solar 系列示例正是这种"无按钮纯滑动"的形态。

3.4 测试佐证

仓库自带的单元测试(Demo/Demo Files/OnboardTests/OnboardTests.m)验证了上述 API 的关键行为:testContentViewControllers校验内容页数组的正确传递;testActionHandler与testActionHandlerWithOnboardController校验按钮回调会被触发、且actionBlock能拿到宿主OnboardingViewController;testDefaultValues确认shouldMaskBackground默认开启、shouldBlurBackground默认关闭。

四、Demo 工程中的三种玩法:AppDelegate 源码拆解

想要复刻画廊里的示例,最直接的参照是 Demo 工程的 AppDelegate.m,它用同一个框架实现了三种完全不同的引导方案。

4.1 标准图片背景玩法(generateStandardOnboardingVC)

这是最经典的形态:以street图片为背景,三个内容页分别使用blue、red、yellow图标,按钮依次为 "Enable Location Services"、"Connect With Facebook"、"Get Started"。要点包括:

  • 第一个按钮的 action 弹窗演示"请求权限"场景,说明引导页是请求定位/推送等权限的最佳时机;
  • 第二个内容页设置movesToNextViewController = YES,实现"点击按钮自动翻页";
  • 第二个内容页设置viewDidAppearBlock,页面出现时弹窗,演示生命周期钩子;
  • 控制器开启shouldFadeTransitions、fadePageControlOnLastPage、fadeSkipButtonOnLastPage,并启用allowSkipping+skipHandler。

4.2 视频背景玩法(generateMovieOnboardingVC)

以项目内的sun.mp4视频作为背景,内容页不设图标、无按钮,纯文字引导。此玩法示范了:

  • 用initWithTitle:body:image:buttonText:action:且参数传nil创建"纯文字页";
  • 通过暴露的titleLabel/bodyLabel属性替换自定义字体(SFOuterLimitsUpright、NasalizationRg-Regular、SpaceAge)和文字颜色;
  • 关闭遮罩(shouldMaskBackground = NO),因为视频本身不需要压暗;
  • 直接修改暴露的pageControl的currentPageIndicatorTintColor/pageIndicatorTintColor定制页码颜色。

4.3 内容页内嵌视频玩法(generateContentVideoOnboardingVC)

第三种玩法让视频直接出现在内容页内部:每个页面用contentWithTitle:body:videoURL:buttonText:action:传入同一个movieURL,背景设为纯黑。它证明了 Onboard 的灵活性——视频既可以作为全局背景,也可以作为单页内容的一部分(源码见 Source/OnboardingContentViewController.m 中基于AVPlayerViewController的内容页视频实现)。

五、让页面更有质感:间距与元素定制

画廊中不同示例的版式差异,主要来自两组定制能力。

第一组是页面四元素的直接定制。iconImageView、titleLabel、bodyLabel、actionButton四个属性全部对外暴露(Source/OnboardingContentViewController.h),可以任意修改字体、字号、颜色等。

第二组是元素间距。README 给出的定制示例:

onboardingVC.topPadding = 20; onboardingVC.underIconPadding = 10; onboardingVC.underTitlePadding = 15; onboardingVC.bottomPadding = 20;

源码中这些属性的含义与默认值(Source/OnboardingContentViewController.m)如下:

属性含义默认值
topPadding屏幕顶部到图标顶部的间距60
underIconPadding图标底部到标题顶部的间距30
underTitlePadding标题底部到正文顶部的间距30
bottomPadding按钮底部到页码指示器的间距0
underPageControlPadding屏幕底部到页码指示器的间距0

内容宽度固定为屏宽的 90%(kContentWidthMultiplier = 0.9),图标在无图时默认 100×100,标题/正文/按钮默认字号分别为 38/28/24 且使用Helvetica-Light字体。布局代码见viewWillLayoutSubviews(Source/OnboardingContentViewController.m),其中在 iOS 11+ 会自动把安全区底部高度叠加进underPageControlPadding。Demo 的视频玩法里topPadding、underTitlePadding甚至被设为负值/超大值,以适配居中排版——这正是画廊各示例版式差异的来源。

六、背景效果三件套:Mask、Blur、Fade

画廊中多数组示例的背景都经过"压暗"处理,这是 Onboard 默认开启的遮罩效果。

6.1 遮罩(shouldMaskBackground)

默认情况下,背景图片上会覆盖一层半透明黑色遮罩以提升文字对比度。如果背景图本身已处理过,可以关闭:

onboardingVC.shouldMaskBackground = NO; // 默认 YES

遮罩的透明度常量是kBackgroundMaskAlpha = 0.6(Source/OnboardingViewController.m),实现上是在背景之上叠加一个 alpha 为 0.6 的纯黑UIView(Source/OnboardingViewController.m)。

6.2 模糊(shouldBlurBackground)

给背景图片加高斯模糊效果:

onboardingVC.shouldBlurBackground = YES; // 默认 NO

模糊并非使用现成 API,而是通过 Accelerate 框架的vImageBoxConvolve_ARGB8888做三次 box-blur 来近似高斯模糊,并叠加饱和度提升(kDefaultSaturationDeltaFactor = 1.8)与白色 tint(白 0.7、alpha 0.3),完整实现见blurBackground(Source/OnboardingViewController.m)。模糊半径默认 20(kDefaultBlurRadius),并按屏幕 scale 换算为像素半径后强制为奇数,以保证 box-blur 三次卷积的近似质量。

6.3 淡入淡出(shouldFadeTransitions)

onboardingVC.shouldFadeTransitions = YES; // 默认 NO

开启后,滑动翻页时当前页的图标/文字/按钮逐渐淡出,下一页的内容逐渐淡入。实现原理比较巧妙:UIPageViewController内部其实是一个UIScrollView,Onboard 在generateView中遍历子视图找到该 ScrollView 并把自己设为 delegate(Source/OnboardingViewController.m),随后在scrollViewDidScroll(Source/OnboardingViewController.m)里根据contentOffset.x计算翻页百分比,调用每个内容页的updateAlphas:同步调整四个元素的 alpha(Source/OnboardingContentViewController.m)。同一回调里还支持fadePageControlOnLastPage与fadeSkipButtonOnLastPage——滚动到最后一页时页码指示器/跳过按钮自动淡出。

6.4 重要:属性必须在 viewDidLoad 之前设置

README 特别提醒:以上视觉效果只在控制器viewDidLoad时生效(generateView在此调用)。如果先访问了onboardingVC.view(例如设置view.backgroundColor)导致视图提前加载,再设置这些属性就不会生效。正确写法是先全部设置完,再展示/访问视图。

不同组合可以产生完全不同的观感,README 给出了四张对照效果图:normal.png(无遮罩无模糊)、dark.png(遮罩压暗)、lightblur.png(模糊无遮罩)、darkblur.png(遮罩 + 模糊)。

七、流程控制:自动导航、禁用滑动与页码淡出

引导流程既可以完全交给用户滑动,也可以由框架主导:

contentVC.movesToNextViewController = YES; // 点击按钮自动翻到下一页 onboardingVC.swipingEnabled = NO; // 禁止用户滑动翻页 onboardingVC.fadePageControlOnLastPage = YES; // 最后一页淡出页码指示器

movesToNextViewController设置在非最后一页的内容页上,点击动作按钮时,handleButtonPressed会先委托宿主执行moveNextPage(Source/OnboardingContentViewController.m),moveNextPage内部用UIPageViewController向前翻一页并同步页码(Source/OnboardingViewController.m)。swipingEnabled = NO时,pageVC的 dataSource 被置为 nil,UIPageViewController便失去滚动数据源,从而实现"只能靠按钮前进"的强引导模式。

需要说明一点事实:README 中写的是onboardingVC.hidePageControl = YES,但核对当前版本源码 Source/OnboardingViewController.h 后发现,公开接口中并不存在hidePageControl属性;当前版本实际提供的能力是fadePageControlOnLastPage(翻到最后一页时淡出页码)和直接暴露的pageControl属性(可自行隐藏或定制颜色)。如果你的目标就是"完全不显示页码指示器",应直接操作pageControl.hidden。

八、跳过引导与生命周期 Block

8.1 允许跳过

onboardingVC.allowSkipping = YES; onboardingVC.skipHandler = ^{ // Dismiss, fade out, etc... };

allowSkipping默认 NO。开启后,右上角会出现 "Skip" 按钮(源码中按钮文字常量kSkipButtonText = @"Skip",尺寸 100×35,Source/OnboardingViewController.m),点击后执行skipHandler完成退出引导。在 Demo 中skipHandler与最后一页的按钮 action 都调用同一个"进入主界面"方法。

8.2 页面出现/消失的 Block

如果需要在内容页出现前后执行某些逻辑,可以在任意内容页上设置四个生命周期 Block:

contentVC.viewWillAppearBlock = ^{ // do something when the view will appear here… } contentVC.viewDidAppearBlock = ^{ // do something when the view appears here… }

对应接口还包括viewWillDisappearBlock与viewDidDisappearBlock(Source/OnboardingContentViewController.h)。源码实现中,这些 Block 会在系统生命周期回调触发时通过dispatch_async派发到主队列执行(Source/OnboardingContentViewController.m)。常见用途包括:页面出现时触发埋点、播放音效、或像 Demo 那样弹出权限引导提示。

九、工程化落地建议

9.1 竖屏限制

README 明确说明当前版本不主动支持横屏,建议仅在竖屏 App 中使用,或将其包装进一个只支持竖屏的子类UINavigationController。

9.2 只对首次用户展示

Demo 工程演示了标准做法:用NSUserDefaults记录user_has_onboarded标记,已引导过的用户直接进入主界面,首次用户才设置引导控制器为 root(AppDelegate.m),引导完成后再切换到主界面(handleOnboardingCompletion)。这套"一次性引导"的模式可直接移植到自己的 App。

9.3 项目维护状态

README 声明 Onboard 已不再积极开发维护,提交的 Issue 与 Pull Request 很可能不会被合并。因此在生产环境使用前,建议评估其 API 是否满足需求,并结合 iOS 版本迭代自行测试。

十、许可证

Onboard 基于 MIT 许可证发布,详见 LICENSE.txt,可自由用于商业项目。

  • 移动开发
  • UI组件

【免费下载链接】Onboard

An iOS framework to easily create a beautiful and engaging onboarding experience with only a few lines of code.

项目地址:https://gitcode.com/gh_mirrors/on/Onboard
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 18:05:28

用C语言读写STL文件:二进制与ASCII格式解析实战

看到标题里的“stl”,估计不少人的第一反应是:C标准模板库?怎么又和C语言文件读写凑一块了?这里先澄清一下,我们要聊的是另一种STL——STereoLithography,也就是3D打印和CAD领域最常见的三角网格文件格式。…

作者头像 李华
网站建设 2026/10/15 18:02:48

网络排障必备的8个命令,从原理到实战一次讲透

搞网络维护或者经常帮人处理电脑问题的人,应该都见过这种场景:打开命令行,敲字母,回车,屏幕滚出一堆数字和英文,懂的人三秒定位问题,不懂的人只能截图到处问。其实这些网络命令就是操作系统自带…

作者头像 李华
网站建设 2026/10/15 18:01:32

Python八股文PDF怎么背才有效?从对象模型到GIL的面试突围指南

简介:这是一份面向 Python 求职者与基础学习者的面试知识点速查 PDF,聚焦生成器、迭代器、列表与元组、字典实现、GIL 全局解释器锁、Py2/Py3 差异、可变与不可变对象、闭包与装饰器等高频问题,以问答形式给出精炼结论与代码示例,…

作者头像 李华
网站建设 2026/10/15 18:01:23

反诈剧情模拟:12个真实骗局,你能识破几个?

一款以真实诈骗话术为蓝本的情景化反诈互动演练产品。体验者以第一人称进入陌生来电与可疑信息的现场,在完整还原的诈骗剧本中做判断、下决定,从"被动听讲"转为"亲身推演"。每一次选择都会改变风险走向与最终结局,结束后…

作者头像 李华
网站建设 2026/10/15 18:01:04

鸿蒙OS集成React Native:组件封装与跨端实践指南

最近在推进跨端方案时,我最常被问到的一句话就是:“React Native 能不能直接跑鸿蒙?”我一般会给一个更精确的答复:业务逻辑可以复用,但组件这一层需要按鸿蒙的原生规范重新包装一次,才能做到“一份业务代码…

作者头像 李华