旋转拨盘控制的核心动画困难(非常详细)

2023-12-30

我正在尝试创建一个旋转拨号控件,基本上是一组 6 位数字,它们不断旋转以产生旋转数字计的效果(类似于您的电表/水表,或者可能是扑克机,实际上与现有的 UIPickerView 控件,但具有完全不同的外观和感觉)。

到目前为止,我几乎可以正常工作了,但我正处于核心动画让我感到悲伤的阶段。

它非常复杂,因此代码片段很难给出正在发生的事情的良好快照,所以我认为伪代码就足够了。

首先,在视图设置方面,我有 6 个独立的UIViews(称为 NumberView1、NumberView2 等),每个控件中的每个数字。

在每个 NumberViewX 中我有另一个UIView,这是一个容器视图,称为ContainerView1、2等...

然后我有10个UIImageView以不同的 Y 偏移量彼此堆叠。这些图像都是 30x30,非常漂亮。首先是 9,然后是 y 偏移量 30 处的 8,然后是 y 偏移量 60 处的 7,等等……一直到 y 偏移量 270 处的 0。

重要提示:我的号码只会向上滚动

这些数字代表 5 位小数点数字(即 2.34677),该数字向上滚动(例如,滚动到 2.61722)。

我还有一些字典,其中保存每个数字的当前数值以及每个数字的偏移量:

NSArray *offsets = [[NSArray alloc] initWithObjects: 
                    [NSNumber numberWithInt:0],    //9
                    [NSNumber numberWithInt:-30],  //8
                    [NSNumber numberWithInt:-60],  //7
                    [NSNumber numberWithInt:-90],  //6
                    [NSNumber numberWithInt:-120], //5
                    [NSNumber numberWithInt:-150], //4
                    [NSNumber numberWithInt:-180], //3
                    [NSNumber numberWithInt:-210], //2
                    [NSNumber numberWithInt:-240], //1
                    [NSNumber numberWithInt:-270], //0
                    nil];

NSArray *keys = [[NSArray alloc] initWithObjects: 
                 [NSNumber numberWithInt:9],
                 [NSNumber numberWithInt:8],
                 [NSNumber numberWithInt:7],
                 [NSNumber numberWithInt:6],
                 [NSNumber numberWithInt:5],
                 [NSNumber numberWithInt:4],
                 [NSNumber numberWithInt:3],
                 [NSNumber numberWithInt:2],
                 [NSNumber numberWithInt:1],
                 [NSNumber numberWithInt:0], nil];

offsetDict = [[NSDictionary alloc] initWithObjects:offsets forKeys:keys];

[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:2] forKey: [NSValue valueWithNonretainedObject: self.containerViewDollarSlot1]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:8] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace1]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:3] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace2]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:3] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace3]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:8] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace4]];
[currentValuesForDecimalPlace setObject:[NSNumber numberWithInt:5] forKey: [NSValue valueWithNonretainedObject: self.containerViewDecimalPlace5]];

现在对于逻辑,我开始将 ContainerView 的图层属性设置为 Y 的某些偏移量,这会将当前数字移动到正确的位置,如下所示:

self.containerViewDollarSlot1.layer.transform =   CATransform3DTranslate(self.containerViewDollarSlot1.layer.transform, 0, -210, 0);
self.containerViewDecimalPlace1.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace1.layer.transform, 0, -30, 0);
self.containerViewDecimalPlace2.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace2.layer.transform, 0, -180, 0);
self.containerViewDecimalPlace3.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace3.layer.transform, 0, -180, 0);
self.containerViewDecimalPlace4.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace4.layer.transform, 0, -30, 0);
self.containerViewDecimalPlace5.layer.transform = CATransform3DTranslate(self.containerViewDecimalPlace5.layer.transform, 0, -120, 0);

这将显示数字 2.83385,这是出于测试目的的任意数字。

然后我在文本框中输入另一个值,然后点击启动按钮,启动动画逻辑,这就是我在核心动画中遇到困难的地方(如标题所示)

I call:

[self animateDecimalPlace: 0
            withAnimation: self.dollarSlot1Animation
         andContainerView: self.containerViewDollarSlot1];
[self animateDecimalPlace: 1 
            withAnimation: self.decimalPlace1Animation 
         andContainerView: self.containerViewDecimalPlace1];
//etc... for all 6 numbers

其中dollarSlot1Animation是CABasicAnimation ivar

该方法定义如下:

- (void) animateDecimalPlace: (int) decimalIndex withAnimation: (CABasicAnimation*)animation andContainerView: (UIView*) containerView{

NSRange decimalRange = {decimalIndex == 0 ? 0 : 2,  
                        decimalIndex == 0 ? 1 : decimalIndex};

double diff = 0;
if (decimalIndex == 0)
{
    int decimalPartTarget = [[[NSString stringWithFormat:@"%f", targetNumber] substringWithRange: decimalRange] intValue];
    int decimalPartCurrent = [[[NSString stringWithFormat:@"%f", currentValue] substringWithRange: decimalRange] intValue]; 
    diff = decimalPartTarget - decimalPartCurrent;
}
else {
    double fullDiff = targetNumber - currentValue;
    diff = [[[NSString stringWithFormat:@"%f", fullDiff] substringWithRange: decimalRange] doubleValue];
}

animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeRemoved;
animation.duration = 5.0;

NSNumber *n = [currentValuesForDecimalPlace objectForKey:[NSValue valueWithNonretainedObject: containerView]];
NSNumber *offset = (NSNumber*)[offsetDict objectForKey: n];
int rotations = [self setupNumberForAnimation: diff decimalIndex: decimalIndex forContainer: containerView];
int finalOffset = (rotations*30)+([offset intValue]);
CATransform3D translation = CATransform3DMakeTranslation(0, finalOffset, 0);

animation.fromValue = [NSValue valueWithCATransform3D:containerView.layer.transform];
animation.toValue = [NSValue valueWithCATransform3D:translation];
animation.delegate = self;
[containerView.layer addAnimation: animation forKey: [NSString stringWithFormat:@"%i", decimalIndex] ];
}

正如你所看到的(或者也许没有:))我基本上独立地对待每个数字,并告诉它转换到新的 Y 位置,但你可能已经注意到其中的一个方法称为setupNumberForAnimation这是另一个动态添加更多内容的大型方法UIImageViews 到容器 UIViewabove最初的 10 个图像块。

例如,一开始有 10 个图块,如果我想将表盘向上滚动 21 个点(例如,从 3 到 24),我需要在 9 以上添加 15 个新数字,然后为容器的平移设置动画查看最顶部的图像图块。

滚动完成后,我删除动态添加的UIImageViews 并将容器视图的 y 偏移重新定位回 0 到 -270 之间的值(本质上最终达到相同的数字,但删除所有不必要的图像视图)。

这给出了我想要的流畅动画。它有效。相信我 :)

我的问题有两个,首先,当动画停止时,核心动画将动画更改恢复到图层,因为我已经设置了animation.fillMode = kCAFillModeRemoved;我无法弄清楚在动画完成后如何设置容器层的 y 偏移量,我知道这听起来很奇怪,但如果我将 fillMode 属性设置为 kCAFillModeForwards,我尝试的任何操作似乎都不会对该层产生影响。

其次,当动画停止并恢复更改时,动画恢复平移和再次设置它之间会出现微小的闪烁,我不知道如何解决这个问题。

我知道这里有很多细节和特殊性,但是任何有关如何实现这一目标的帮助或想法将不胜感激。

多谢


我记得WWDC10的CoreAnimation视频中有一些关于动画跳回之前状态的问题,您可以从苹果免费下载。

稍后我得查一下,但是当然有委托方法- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag当动画完成时会调用它。这将是一个做家务的好地方。也许你可以通过查看来设置图层的 y 偏移toValue动画的属性。

这只是一个远景,但也许它指向了正确的方向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

旋转拨盘控制的核心动画困难(非常详细) 的相关文章

  • UILocalizedIndexedCollat​​ion的sectionForObject:(id)object collat​​ionStringSelector:(SEL)selector方法中selector的作用是什么

    我是 iOS 开发的初学者 正在经历this https developer apple com library ios documentation UserExperience Conceptual TableView iPhone Cr
  • 我如何知道网页视图已加载完成

    我有网络视图 因为我正在加载pdf文件 pdf 文件大小为 2 mb 因此需要时间 我想添加指标 为此 我如何知道我的文件已加载到网络视图中 UIWebView 委托 http developer apple com library ios
  • 使用 iOS 分布式应用程序时 Google Cloud Messaging 显示“notRegistered”

    我在 iOS 应用程序上实现了 GCM 服务 我使用 PHP 在服务器上发送 GCM 当应用程序由开发配置文件签名时 它可以完美运行 也就是说 当应用程序使用 GCM 配置注册自身时 它始终返回一个正常运行的设备令牌 我可以使用令牌向设备发
  • 当用户到达 UITableView 的最后一行时,如何动态添加行?

    我有一个UITableview当前显示 10 行 固定为静态 现在我想在其中添加一个功能 当用户到达最后一行时 我想向表中添加更多 10 行UITableView 我的意思是目前我在应用程序中显示固定的 10 行 但现在我想在用户到达上一个
  • 带有子视图的 UIView beginAnimations

    我有一个漂亮且简单的视图 缩放 动画 它以一个点开始并动画到全屏尺寸 UIView beginAnimations nil context NULL UIView setAnimationBeginsFromCurrentState YES
  • 允许的 APNS 持续连接数量是多少?

    我正在尝试编写服务器端代码来为我的应用程序发送推送通知 根据 Apple 的建议 我计划保留连接并根据需要发送推送通知 Apple 还允许打开和保留多个并行连接以发送推送通知 您可以与同一网关或多个网关实例建立多个并行连接 为此 我想维护一
  • iPhone 相当于 Application.DoEvents();

    iPHone 我们使用 MonoTouch 但 Obj C 答案还可以 我的单例域对象需要一段时间才能获取所有数据 因此它在线程中内部运行部分获取数据 我需要通知 UI 域已完成 目前我正在这样做 有没有更好的办法 在 WinForms 中
  • 您是否标记 UIView 或将它们保留为属性?

    这主要是一个风格问题 但自从我开始为 iPhone 编程以来 我一直很好奇其他人的想法是什么 当您的 iPhone 应用程序中有一个 UIView 并且需要在应用程序的其他位置访问它时 通常在视图控制器中的另一个函数中 您是否喜欢用整数标记
  • 最小的 iOS 蓝牙管理器示例

    我一直在构建一个最小的示例 用于使用 iOS 5 0 中的 BluetoothManager 私有框架来检测附近的蓝牙设备 使用此问题中找到的答案 寻找触手可及的通用蓝牙设备 https stackoverflow com question
  • 打乱 NSMutableArray 而不重复并显示在 UIButton 中

    在我看来 我有 12 个按钮 一个数组包含 6 个名称 我想在其中打印数组名称UIButton标题 这是我的代码 texts NSMutableArray alloc initWithObjects 1 2 3 4 5 6 nil UIBu
  • XCode 无法将 iPhone 应用程序部署到 iPhone 3GS

    因此 我构建了我的 iPhone 应用程序 它在模拟器中运行良好 因此我想将其部署到我的 iPhone 上进行最后一轮测试 然后再使用我的分发配置文件进行公开 Beta 测试 我已经这样做过很多次了 从来没有出现过问题 然而 自从上次测试运
  • 在横向中自动调整 UITableCells 内容的大小

    在 UITableView 中 我通过 UILabels 将内容添加到单元格中 定义最佳尺寸 与单元格宽度允许的一样大 我注意到只有tableView contentSize width是可靠的 因为cell contentView bou
  • 持久化 UINavigationItem 的 rightBarButtonItem 属性

    这可能是一个愚蠢的问题 但是有可能保持正确的吗 UIBarButtonItem跨由一个管理的多个视图UINavigationController 我的一系列观点通常具有相同的权利UIBarButtonItem 但是当我将新视图推送到我的UI
  • 忽略触摸事件,让其下面的视图处理触摸?

    我有一个用户可以触摸的可拖动视图 但它的某些矩形将没有图像 alpha 0 当用户单击透明区域时 我能够在没有 alpha 信息的情况下构造透明区域 我希望透明区域下方的视图 同一类 来检测触摸 我的策略是当用户触摸透明区域时让视图忽略触摸
  • 虚拟乐器 iPhone 应用程序中的 VoiceOver 辅助功能?

    我收到盲人用户的评论 称我的一些声音和音乐相关应用程序只能在关闭 VoiceOver 的情况下使用 在 iOS 设备上启用 VoiceOver 辅助功能后 是否可以启用音乐键盘或鼓垫触摸区域 以便在点击键盘键或虚拟鼓组 等 时可以立即播放音
  • insertNewObjectForEntityForName:

    我使用 Xcode xcdatamodel 文件编辑器设置了一个实体 我创建了一个名为 Person 的实体 添加了一些属性 然后生成了一个 m 文件来表示它 一切都很好 现在 当我去编写一行代码时 例如 Person person Per
  • 如何检测用户是否第一次打开应用程序[重复]

    这个问题在这里已经有答案了 是否可以检测用户是否是第一次打开iOS应用程序 使用Objective C 我想在用户第一次打开应用程序时显示欢迎消息 但之后不再向他们显示 我正在寻找类似的东西 BOOL firstTime AppDelega
  • 有什么方法可以询问方法的名称吗?

    我正在尝试调试我正在开发的 iPhone 应用程序 向各种源文件添加 50 条 NSLog 语句的想法让我感到很兴奋 我想做的是写一对陈述 比如 NSString methodName self methodName NSLog metho
  • 如何删除 UITableView 中的缩进?

    首先 我对此很陌生 我很可能忘记了一些非常简单的事情 问题 我正在制作一个应用程序 在 a 中显示来自 imgur com 的随机图像tableView 由于某种原因 所有单元格都会缩进少量 如下图所示 我摆弄了许多设置storyboard
  • iphone sqlite 静态链接?

    有人静态链接 sqlite 而不是使用动态链接 吗 我遇到的问题是 越狱手机的用户没有与普通 iPhone 所采用的 sqlite 版本相同的版本 因此导致崩溃 我假设在我的应用程序中静态链接已知版本的 sqlite 就是答案 我需要全文支

随机推荐

  • Firebase如何检查交易成功或失败?

    我正在尝试更新事务中的 firebase 节点 简单的事情 按照文档 https www firebase com docs ios guide saving data html https www firebase com docs io
  • 系统启动时哪个核心首先初始化?

    我想知道CPU启动时多核处理器的哪个核心首先初始化 我的意思是在引导加载程序级别 是第一个核心 还是随机核心 您想要阅读本地 apic 您可以在 卷 2a 中阅读 http www intel com content www us en p
  • 如何在R编程中显示同一坐标中的总数

    更新2017年9月11日问题 这是我在 R 中集群 kmode 的代码 library klaR setwd D kmodes data to cluster lt read csv kmodes csv header TRUE sep c
  • 射线和椭球相交精度提高

    我需要提高我的一个功能的精度大气散射 GLSL 片段着色器 https stackoverflow com a 19659648 2521214它计算单射线和轴对齐椭球体之间的交集 这是矿山大气散射着色器的核心功能 旧的原始着色器已打开fl
  • 对 favicon 静态图像的哈希进行摩卡测试失败

    我正在尝试使用 mocha 请求和 SHA1 哈希来编写集成测试 以确认 Express 提供的图标与文件系统上的图标相同 我得到两个不同的哈希值 但不明白为什么 编码有可能改变吗 process env NODE TLS REJECT U
  • ArrayBuffer 到 blob 的转换

    我有一个项目需要在浏览器中显示 djvu 架构 我发现这个老Github 上的库 https github com lebedkin minidjvu js据我了解 它将 djvu 文件转换为 bmp 然后将它们放入 canvas 元素中
  • 如何在 Android 4.2.2 上启用 JavaScript 控制台

    我正在尝试启用 JavaScript 控制台来调试运行 4 2 2 的 Samsung Galaxy S4 上的原生 Android 浏览器中的网页 在 S3 上 我只需在地址栏中输入 about debug 就会出现 但它在 S4 上不起
  • WPF 双向绑定 XML

    我正在努力掌握 WPF 更具体地说 是执行 xml 文件的双向绑定 我应该使用 XMLDataProvider 还是他们的另一个 更好 选择 数据显示正常 但当我更改条目时 更改不会反映在 xml 文件中 The XML
  • Jenkins 中颠覆轮询失败的电子邮件通知

    由于密码更改 我们在 Jenkins 中的一项工作失败了 它的颠覆轮询超过 24 小时 当这种情况发生时 并不是立即显而易见的 除非您注意到作业没有运行并实际检查日志 构建不会失败 因为它从未启动 有没有人找到解决方案来通知 Jenkins
  • Spark中如何获取数组列的所有组合?

    假设我有一个数组列group ids user id group ids 1 5 8 3 1 2 3 2 1 4 Schema root user id integer nullable false group ids array null
  • Composer 未下载包的 src 目录

    我正在使用 Laravel 和 Composer 构建一个网络应用程序 在我的本地计算机上 我在composer json 文件中设置了其要求 并且一切正常 我正在使用 Github 推送到生产服务器 但是 然后我运行composer in
  • 我能否获取 C#/WPF 中绑定对象的 Type()(即使绑定值为 null)?

    我与未知来源有绑定 我所拥有的只是绑定 我没有其他方法来查看绑定对象 我需要找出绑定对象的类型 即使该值为空 这就是我的问题所在 我通过绑定到一个对象然后使用该对象作为获取类型的方式来评估绑定 但即使该值为 null 我也需要知道该类型 例
  • 使用 pytest 时如何组织装置

    固定装置往往较小且可重复使用 鉴于特定装置可以依赖其他装置 pytest fixture def Account db memcache 我想在模块中组织我的装置 并将它们导入到特定的测试文件中 如下所示 例如 from fixtures
  • 从 XP 中的隐藏或剪切窗口复制内容?

    我需要将隐藏窗口 BitBlt 的内容复制到另一个窗口 问题是 一旦我隐藏源窗口 我得到的设备上下文就不再被绘制 你需要的是打印窗口 http msdn microsoft com en us library ms535695 aspx从
  • airodump-ng 使用 python subprocess.Popen 通信方法输出

    嗨 我正在尝试从中获得连续输出airodump ng mon0 因此 我试图读取的输出airodump ng mon0经过一段时间与 Popen communicate 但仍然无法得到任何东西 import subprocess airod
  • 如何在backbone.js中创建基本视图?

    我需要创建一个基本视图 我的所有视图都会扩展 我不太确定何时何地声明这个观点 基本上 我需要注入global variables我的所有模板 但我不会在每个模板中都这样做render 方法 这是我现在的树结构 main js app js
  • MySQL 更新查询 - 竞争条件和行锁定会遵守“where”条件吗? (PHP、PDO、MySQL、InnoDB)

    我正在尝试建立一个先到先得的模型销售页面 我们有 n 个相同类型的物品 我们希望将这 n 个项目分配给前 n 个发出请求的用户 每个项目对应有一个数据库行 当用户按下购买按钮时 系统会尝试查找尚未出售的条目 reservationCompl
  • .用曲线制作动画

    首先看一下 猫需要移动到 a 中的 xcurve 见箭头 当猫击中 x 时 应停留 10 秒 然后猫应返回 o 再次呈曲线状 然后重复 我用这段代码尝试过 function curve cat delay 10000 animate top
  • Webpack 从 /folder/folder.js 而不是 /folder/index.js 导入

    使用 webpack 当我在 blah 中创建一个 index js 时 然后执行import blah from blah 它成功地从index js获取 但是 我的代码编辑器现在充满了名为 index js 的选项卡 并执行 Ctrl
  • 旋转拨盘控制的核心动画困难(非常详细)

    我正在尝试创建一个旋转拨号控件 基本上是一组 6 位数字 它们不断旋转以产生旋转数字计的效果 类似于您的电表 水表 或者可能是扑克机 实际上与现有的 UIPickerView 控件 但具有完全不同的外观和感觉 到目前为止 我几乎可以正常工作