原文:How We Developed ColorMatchTabs Animation for iOS
在应用中有很多方式去组织导航栏:tab bars
、side menus
、Tinder-like swipes
,然而,大多数现有的解决方案都有一个问题,对于大屏幕手机是很不方便的,用户必须通过去不断地点击图标来切换屏幕。
我们决定分享我们创建用户界面动画的概念,解决了在大屏幕上的应用程序导航的问题。
[ ColorMatchTab
动画,在 Dribbble
和 Github
可以查看]
ColorMatchTab动画有什么用?
开发这个动画是为了说明一个概念在我们开发的一款评论应用,这个应用将显示用户周围的有趣的地方,也可以他们留下评论和阅读其他人留下的评论。动画显示了四种不同的类别:产品、地点、评论和朋友,就像四个不同的屏幕。
我们在 Relativewave
完成了这个动画的原型,Relativewave
是一个非常好的制作原型的工具。
在 ColorMatchTab
动画我们为了区分不同的类型的 tab bar
采用了彩色的图标。为了避免混乱,每个图标,以及每个颜色,都是唯一的一个特定类别。当 tab bar
的其中一栏变成活跃,一个填充着相应的颜色,并且出现相应的分类标题的圆角矩形使它非常突出,这样非常清楚哪些tab bar
是当前活跃的。
用户所看到屏幕是整体的一部分,通过应用引导用户进一步了解每个屏幕。Call-to-action
按钮很容易发现,并帮助用户用自己的方式了解应用。
我们使用了 FAB
(浮动操作按钮)来创建一个 Call-to-action
,是很难不被注意到的。容易实现在屏幕底部中间部分创建这个按钮,特别是对更大屏幕的设备。
当我们的设计师创造了这个概念后,我们的任务给动画带来生命力。
正如你可以看到下面,我们开发了几个动画组件:一个底部栏,一个顶部栏,有内容的页面,和屏幕的转场。每一个组件都有开发难点。
底部按钮
为了实现这个底部按钮我们调整每个元素,使它们从圆心等距。开发人员可以根据他们的需要改变圆的半径,从而在圆的周围调整元素的位置。您还可以调整尺寸大小和动画持续时间,并选择您喜欢任何图像作为图标。
顶部栏
一年前,苹果宣布了一项新的UI组件称为 UIStackView
( WWDC session
和 Apple’s documentation
)。 UIStackView
允许你创建多个没有任何约束的成员视图。你只设置分配模式和它怎样工作。在内部机制下,它会自动布局。但这对你来说意味着什么呢?这意味着你不必添加约束,在你需要的的时候你可以这样做。如果视图是隐藏的 UIStackView
也会自动调整约束。
这个实现非常简单 - 我们会展示在 UIStackView
下的各种各样的 UIViews
您可能注意到顶部菜单是导航栏的一部分,有几种方法来实现一个自定义导航栏。苹果有一个很好的示例项目,显示如何创建自定义的导航栏(特别是扩展和自定义导航栏)。我们决定使用一个扩展的导航栏,但您可以选择一个自定义的导航栏来提供更多的原生行为。
页面内容
页面是通过 UIScrollView
构建的,并且包含视图控制器在里面。
通过检测当前索引的内容偏移量,当一个视图超过50%出现在屏幕上。这个索引值将会发生变化,然后我们观察到当前的内容偏移量来检测变化。
当我们从第一个到第四个 tab bar
切换的时候,为了避免屏幕闪烁,我们先隐藏在屏幕的所有内容,然后在切换后再次显示所有内容。这是 ColorMatchTabs
动画的一部分。我们没有使用 UIPageViewController
,这是一个明智的选择,因为它实现起来达不到同样的流畅性能。
我们也不需要重复使用视图控制器,因为 tab bar
预计不会有超过五个(就像 UITabBarController
)。这个类的这个接口也类似于 tab bar
控制器,你所需要做的就是设置一个视图控制器的数组
转场
用户按下底部按钮(粉红色按钮),屏幕之间切换时都需要通过转场。
新的视图出现从底部的按钮的中心,逐渐扩大,直到它取代以前的视图。我们实现通过 CircleTransition
类来实现转场动画,并且实现相应的 UIViewControllerAnimatedTransitioning
协议方法。
这个只显示圆内视图,隐藏圆外视图的圆,是通过 CALayer
类 mask
属性实现的,这表明圈内的一切隐藏一切超越它。要达到这种效果我们使用 UIBezierPath
两实例化两个圆圈,一个小尺寸和一个足以覆盖整个屏幕大的圆。我们还创建了一个新的 CAShapeLayer
暂时的圆遮盖,最后的动画发生在这两个轨迹之间。
控制器使用的动画遵循 UIViewControllerAnimatedTransitioningDelegate
协议。接受该协议控制器,我们要显示或隐藏,并要求我们返回一个接受 UIViewControllerAnimatedTransition
协议的对象。
这个转场具有以下属性:
- 起点处— 动画这一点是在按钮的中心,也是动画在屏幕上消失的一个点
- 持续时间— 持续多长时间
- 模式— 一个可能的动画模式列表(隐藏和显示)
Dropping items
Dropping items
可能是 ColorMatchTab
动画最有趣的部分。我们需要能够将图标从动画的一个元素移动到另一个元素。要做到这一决定,我们决定使用临时图标。一旦临时图标到达他们的目标在屏幕上,在当前的动画组件中隐藏它们,并显示真正的图标。
为了确保这些图标正确显示在不同的屏幕尺寸上,我们必须做以下几方面:
- 显示
tab bar
顶部的临时图标 - 隐藏
tab bar
的图标 - 在主屏幕上临时图标的转场动画
- 在模式视图控制器上显示临时图标
- 在模式视图控制器上临时图标的转场动画
- 在模式视图控制器上隐藏临时图标
菜单控制器
如果你想完全利用屏幕上所有的动画显示,你必须为 MenuViewController
设置数据源。该数据源允许您自定义视图控制器、标题、颜色、图标:
public protocol ColorMatchTabsViewControllerDataSource: class {
func numberOfItems(inController controller: ColorMatchTabsViewController) -> Int
func tabsViewController(controller: ColorMatchTabsViewController, viewControllerAt index: Int) -> UIViewController
func tabsViewController(controller: ColorMatchTabsViewController, titleAt index: Int) -> String
func tabsViewController(controller: ColorMatchTabsViewController, iconAt index: Int) -> UIImage
func tabsViewController(controller: ColorMatchTabsViewController, hightlightedIconAt index: Int) -> UIImage
func tabsViewController(controller: ColorMatchTabsViewController, tintColorAt index: Int) -> UIColor
}
我们也提供了一个示例应用程序,所以你可以打开它,运行和学习如何将它使用在您的应用中。
总结
我们希望我们实现的这个 tab bar
是对你有用的,尤其是看到它在屏幕之间非常流畅的滑动。我们将组件分成几个部分描述,以便你可以将它作为单独的项目或作为一个整体来使用。
如果你在你的 Apps
中使用我们的解决方案,我们将很高兴。我们喜欢分享我们的经验,并总是高兴地讨论我们的工作。如果你决定在你的应用中使用我们的部件,不要犹豫与我们联系,我们将您添加到 'Readme' 中。如果你碰巧发现我们的部件有问题,在GitHub库创建一个问题,我们会很乐意帮助你!
ColorMatchTab
动画,在 Dribbble
和 Github
可以查看。