ios开发——仿新版iBooks书本打开与关闭动画

简介:

IOS新版iBooks吸引人的地方除了有干净整洁的界面、方便灵活的操作以及大容量的书籍容量以外。还有其优秀的用户交互,尤其是其动画的使用。打开一本书时书本缓慢放大并打开。关闭一本书后书本关闭并回到原位置。

如今我们来实现这个简单的功能。


效果图:



用到的知识:

1、CAKeyframeAnimation的应用

2、怎样在代理中区分两个不同的动画

3、坐标系转换


思路:

这个动画主要用到的是CAAnimation,而且是CAKeyframeAnimation。当用户点击书本时。设置一个UIImageView(为其加上tag方便以后取)并将其放在选中书本的位置上(使用坐标系转换)。接着通过动画将其放大到全屏,完毕后将其锚点设置为(0,0.5)并让其绕y轴选中π/2角度,将早已放在以下的textView(本app中是自己定义的readView)展示出来。

动画完毕后将UIImageView的透明度设为0。这样就是书本的打开过程。

关闭过程类似,依据tag取出UIImageView并将其旋转,然后设置frame到原来书本的位置(能够用私有变量记录该位置),最后removeFromSuperview就可以。


代码:

首先是“准备阶段”

    //BookReadView是展示textView和顶部底部附加view的自己定义view
    CYZBookItemView *itemView = [notification object];
    CYZBookReadView *readView = [[CYZBookReadView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height) ItemView:itemView];
    //设置delegate是为了当用户从阅读界面返回时做出响应
    readView.delegate = self;
    //先将其alpha设为0防止用户刚点击书本动画还在进行中时就出现这一界面
    readView.alpha = 0.0f;
    [self.view addSubview:readView];
    
    //展示动画的UIImageView
    UIImageView *showView = [[UIImageView alloc] initWithImage:itemView.bookImage.currentBackgroundImage];
    //坐标系转换
    _itemPosition = [itemView.superview convertRect:itemView.frame toView:self.view];
    showView.frame = _itemPosition;
    //设置tag方便以后取出
    showView.tag = 1001;
    showView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:showView];

关于坐标系转换( 以矩形为例。point类似):


- (void)convertRect:toView:方法:

格式[被转换者所在的View convertRect: 被转换者的frame或bounds toView:转换到的View];返回在目标View中的rect

比如,将当前视图的子视图viewA中的一个imageView转换到当前视图。

能够例如以下调用:

[viewA convertRect:viewA.imageView.frame toRect:self.view];

或者[imageView.superView convertRect:imageView.frame toRect:self.view];

当中self指控制器。


- (void)convertRect:fromView:方法:

格式[要转换到的View convertRect: 被转换者的frame或bounds fromView:被转换者所在的View];返回在目标View中的rect。

还是上一个样例,能够这样写:

[self.view convertRect:viewA.imageView.frame fromView:viewA];

或者[self.view convertRect:imageView.frame fromView:imageView.superView];

当中self指控制器


接着准备工作完毕了以后就能够開始动画了。

一下是打开动画的部分

    [UIView animateWithDuration:0.5f animations:^{
        //将UIImageView放大为全屏
        showView.frame = self.view.bounds;
    } completion:^(BOOL finished) {
        if (finished) {
            //展示出readView
            readView.alpha = 1.0f;
            
            //设置锚点
            showView.layer.anchorPoint = CGPointMake(0, 0.5);
#warning 不知道为什么,不加以下这句话showView会显示异常:即仅仅显示一半
            showView.frame = CGRectMake(0, 0, showView.width, showView.height);

            CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
            //设置其绕y轴旋转
            animation.keyPath = @"transform.rotation.y";
            //设置持续时间。能够定义一常量来表示
            animation.duration = 0.5f;
            animation.speed = 0.55f;
            animation.removedOnCompletion = NO;
            //旋转π/2度
            [animation setValues:[NSArray arrayWithObjects:@0.0f, @-M_PI_2, nil]];
            //设置代理便于回调
            animation.delegate = self;
            //这里必须设置上key,为了接下来区分不同动画
            [showView.layer addAnimation:animation forKey:@"rotateToOpenBook"];
        }
    }];

代码中凝视已经解释得比較具体了,仅仅只是正如warning写得那样。本来我是用showView.layer.transform来实现动画的,这样会省非常多事。比方不用在代理中区分动画、不用记录position来在方法间传值等,只是不知道为什么showView总是仅仅显示一半。求解释╮(╯▽╰)╭


回调中:

[showView setAlpha:0.0f];

将其临时隐藏。关上书时还要用它。


关上书的动画大致类似

#pragma mark - CYZBookViewDelegate

- (void)readViewDidBackWithItem:(CYZBookItemView *)item
{
    //取出showView
    UIImageView *showView = (UIImageView *)[self.view viewWithTag:1001];
    //将其显示出来
    showView.alpha = 1.0f;
    showView.layer.anchorPoint = CGPointMake(0, 0.5f);
    showView.frame = CGRectMake(0, 0, showView.width, showView.height);
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"transform.rotation.y";
    animation.duration = 0.5f;
    animation.speed = 0.55f;
    animation.removedOnCompletion = NO;
    //反向旋转
    [animation setValues:[NSArray arrayWithObjects:@-M_PI_2, @0, nil]];
    animation.delegate = self;
    //设置不同的key为了区分动画用
    [showView.layer addAnimation:animation forKey:@"rotateToCloseBook"];
    
}

这里要用一个不同的key来表示这个动画。

该动画的回调:

            [UIView animateWithDuration:0.5f animations:^{
                showView.frame = _itemPosition;
            } completion:^(BOOL finished) {
                [showView removeFromSuperview];
            }];

_itemPosition是之前用来记录转换的坐标的私有变量,这几行代码的意思就是让showView回到书本的位置然后令其消失。

这里的关键问题在于。两个动画都用到了回调,怎样区分呢?就用我们之前设置的key来区分:

回调的完整代码:

#pragma mark - AnimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    UIImageView *showView = (UIImageView *)[self.view viewWithTag:1001];
    if (flag) {
        if (showView && [[showView.layer animationForKey:@"rotateToOpenBook"] isEqual:anim]) {
            [showView setAlpha:0.0f];
        } else if (showView && [anim isEqual:[showView.layer animationForKey:@"rotateToCloseBook"]]) {
            [UIView animateWithDuration:0.5f animations:^{
                showView.frame = _itemPosition;
            } completion:^(BOOL finished) {
                [showView removeFromSuperview];
            }];
        }
    }
}
通过showView所在层layer的方法 animationForKey:获得自己设置的动画,与代理中的anim做比較就可以区分。

另外。在stackOverflow上还看到一种方法:用kvc的方法为animation设值,并在代理中通过kvc的方法依据这个键取出值并进行推断,应该也是能够的。





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5360373.html,如需转载请自行联系原作者

相关文章
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
1月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
143 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
2月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
90 11
|
2月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
145 66
|
2月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
173 3
|
2月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
3月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。
|
3月前
|
安全 IDE Swift
探索iOS开发之旅:从初学者到专家
在这篇文章中,我们将一起踏上iOS开发的旅程,从基础概念的理解到深入掌握核心技术。无论你是编程新手还是希望提升技能的开发者,这里都有你需要的指南和启示。我们将通过实际案例和代码示例,展示如何构建一个功能齐全的iOS应用。准备好了吗?让我们一起开始吧!
|
3月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
3月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
72 2

热门文章

最新文章

  • 1
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 3
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 6
    iOS8 中无需开源库的内置功能一览
  • 7
    iOS7应用开发7:自定义视图、手势操作
  • 8
    IOS小工具以及精彩的博客
  • 9
    Facebook SDK(iOS)初学讲解
  • 10
    iOS - Swift NSPoint 位置
  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    14
  • 2
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    28
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    34
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 6
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    143
  • 7
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    235
  • 8
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    90
  • 9
    深入探索iOS开发中的SwiftUI框架
    145
  • 10
    ios样式开关按钮jQuery插件
    60