问题现象

因为 Facebook 的 POP 框架用起来很舒服,于是一直慢慢来习惯了用 POP 做动画,最近做了一个很简单的让一个 Button 旋转的动画,程序却异常的崩溃了,崩溃的地方在 -layoutSubviews 这个地方,如下图目测,应该是因为动画的时候,触发了 -layoutSubviews 方法,于是崩溃,就像这样

Crash

并且在终端输出了这样的信息

Jun 27 07:05:17  shenzhenren[5868] <Error>: CGAffineTransformInvert: singular matrix.
Jun 27 07:05:17  shenzhenren[5868] <Error>: CGAffineTransformInvert: singular matrix.

原因分析

我们先来看下关键的几处代码是怎么写的:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {self = [super initWithCoder:aDecoder];if (self) {self.isShowAll = NO;[self loadShowAllButton];}return self;
}- (void)layoutSubviews {[super layoutSubviews];self.showAllButton.top = 8.0f;self.showAllButton.right = self.width;
}- (void)loadShowAllButton {self.showAllButton = [[UIButton alloc] init];[self addSubview:self.showAllButton];self.showAllButton.width = 36.0f;self.showAllButton.height = 36.0f;self.showAllButton.left = 0.0f;self.showAllButton.top = 0.0f;self.showAllButton.contentMode = UIViewContentModeCenter;[self.showAllButton setImage:[UIImage imageNamed:@"default-show-more-arrow"] forState:UIControlStateNormal];[self.showAllButton addTarget:self action:@selector(showAllButtonPushed:) forControlEvents:UIControlEventTouchUpInside];
}- (void)showAllButtonPushed:(UIButton *)sender {self.isShowAll = !self.isShowAll;POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];if (self.isShowAll) {animation.toValue = @M_PI;} else {animation.toValue = @0;}[sender pop_removeAllAnimations];[sender pop_addAnimation:animation forKey:nil];
}

上面的代码并不复杂,我想要实现的东西就是在点击按钮的时候,让他旋转180度,再次点击的时候让他转回来

那么根据上面代码,崩溃的过程其实是这样的:

  1. 点击按钮,触发 POP 动画
  2. POP 的动画为 UIView 添加对应的 Transform,同时产生动画
  3. 因为 UIView 添加了 Transform,所以 UIView 触发了需要重新计算 layout 的过程
  4. 调用 - (void)layoutSubviews 重新计算布局
  5. 因为 UIView 有 Transform 了,再通过 -setFrame:(GRect)frame 设置 UIView 的 frame 出现错误,参考官方文档

如何解决

既然找到了原因,那么我们就根据原因来跳坑吧,既然是触发了 View 重新计算布局,那么我们不要让他在这个父 View 触发即可,那么最简单粗暴的解决方法就是,创建一个新的 View 包裹住我们需要动画的 View 于是,这样修改

- (void)layoutSubviews {[super layoutSubviews];self.showAllButtonContainerView.top = 8.0f;self.showAllButtonContainerView.right = self.width;
}- (void)loadShowAllButton {self.showAllButtonContainerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 36.0f, 36.0f)];[self addSubview:self.showAllButtonContainerView];self.showAllButton = [[UIButton alloc] init];[self.showAllButtonContainerView addSubview:self.showAllButton];self.showAllButton.width = 36.0f;self.showAllButton.height = 36.0f;self.showAllButton.left = 0.0f;self.showAllButton.top = 0.0f;self.showAllButton.contentMode = UIViewContentModeCenter;[self.showAllButton setImage:[UIImage imageNamed:@"default-show-more-arrow"] forState:UIControlStateNormal];[self.showAllButton addTarget:self action:@selector(showAllButtonPushed:) forControlEvents:UIControlEventTouchUpInside];
}

其实问题的原因还是没有好好阅读官方文档

POP Animation 和 layoutSubviews 的冲突相关推荐

  1. 撤消git stash pop导致合并冲突

    本文翻译自:Undo git stash pop that results in merge conflict I began making changes to my codebase, not r ...

  2. Facebook POP 使用指南

    Facebook POP 使用指南 Pop是一个动画引擎,用以扩展iOS.OSX的动画类型.相较于iOS.OSX中的基本动画效果,Pop扩展后支持弹簧动画效果与衰减动画效果,你可以用Pop动画引擎来构 ...

  3. Facebok的动画框架pop

    来源:http://www.jianshu.com/p/1172578c96e1 该开源框架比苹果的Core Animation功能更强大,我强烈推荐该动画框架. Facebook Paper 官网: ...

  4. iOS之POP动画使用和实战

    - POP是一个来自于Facebook,在iOS与OSX上通用的极具扩展性的动画引擎.它在基本的静态动画的基础上增加的弹簧动画与衰减动画,使之能创造出更真实更具物理性的交互动画. - Pop Anim ...

  5. git拉取代码如何解决冲突_Git工具-git pull拉取代码时冲突的解决办法

    一,在使用git pull命令拉取代码时,有时会遇到以下错误信息: error: Your local changes to the following files would be overwrit ...

  6. 交互神器 Facebook Origami

    2019独角兽企业重金招聘Python工程师标准>>> 最近用到了一个非常强大的工具,这是一款由 facebook 出品的原型设计软件,老规矩我们先来看一下效果.大家也可以先进去官网 ...

  7. Facebook开源动画库 POP-POPBasicAnimation运用

    动画在APP开发过程中还是经常出现,将花几天的时间对Facebook开源动画库 POP进行简单的学习:本文主要针对的是POPBasicAnimation运用:实例源代码已经上传至gitHub,地址:h ...

  8. github 【第三章】Github综合

    版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景象! 1 2 3 4 5 6 7 8 9 10 11 毕业论文_初稿.doc 毕业论文_修改1.do ...

  9. Git命令提交项目代码

    Git客户端安装 今天就结合`GitHub`,通过`Git`命令,来了解如何实现开源代码库以及版本控制 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托 ...

最新文章

  1. GCD的其他(不常用)方法
  2. C语言strcpy,strncpy和strlcpy讲解
  3. IOS sqlite数据库增删改查
  4. hdu 5071 Chat(模拟|Splay)
  5. OpenCV 图像清晰度评价算法(相机自动对焦)
  6. 再论数据科学竞赛中的Data Leakage
  7. git 回退上一个版本_Git小白使用教程:详细、显现、真正手把手教!
  8. highcharts 显示平均值数值_拼多多评价多久能显示,有什么出评价技巧吗?
  9. c语言程序设计课程设计心得体会,C语言程序课程设计心得体会
  10. 如何在任何设备上将您的Apple笔记导出为PDF文件?
  11. Atitit ide的艺术 与新特性搜集大纲 目录 1. Prj mana 2 2. 界面布局自定义 2 2.1. 自定义 perspectives 2 3. 代码编写 2 3.1. 自动提示 2
  12. Show一下2008新技术体验活动的奖品
  13. webpack5学习与实战-(六)-babel-loader解析js文件
  14. android模拟gps定位软件,gps定位模拟器下载最新版
  15. 医咖会免费SPSS教程学习笔记—斯皮尔曼相关系数(秩相关系数)
  16. 容器技术—docker stack
  17. 今日总结-20220304
  18. 一文带你了解 sensor
  19. PPT基础(三十)图片的特殊效果
  20. 蜂鸣器干扰通讯_蜂鸣器常见错误电路分析

热门文章

  1. 你应该知道的 8 个Java 的领军人物
  2. rdlc报表的制作步骤
  3. 复变函数系列(三 ) - 复变函数的积分
  4. 深入理解 WordPress 数据库中的用户数据 wp_user
  5. Sublime搭建Python开发环境
  6. Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析
  7. sshd iptable 傻瓜配置
  8. hashMap 根据已有知识知道的
  9. css点滴3—5种方式实现圆环
  10. spring security reactive获取security context