我有一个CAShapeLayer(它是UIView子类的一层),path只要视图的bounds大小发生变化,它就会更新.为此,我重写了图层setBounds:重置路径的方法:
@interface CustomShapeLayer : CAShapeLayer
@end
@implementation CustomShapeLayer
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
self.path = [[self shapeForBounds:bounds] CGPath];
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,直到我为边界变化设置动画.我希望在任何动画边界变化(在UIView动画块中)中创建路径动画,以便形状图层始终采用其大小.
由于该path属性默认没有动画,我想出了这个:
覆盖图层的addAnimation:forKey:方法.在其中,确定是否将边界动画添加到图层.如果是这样,通过复制传递给方法的边界动画中的所有属性,创建第二个显式动画,以便为边界旁边的路径设置动画.在代码中:
- (void)addAnimation:(CAAnimation *)animation forKey:(NSString *)key
{
[super addAnimation:animation forKey:key];
if ([animation isKindOfClass:[CABasicAnimation class]]) {
CABasicAnimation *basicAnimation = (CABasicAnimation *)animation;
if ([basicAnimation.keyPath isEqualToString:@"bounds.size"]) {
CABasicAnimation *pathAnimation = [basicAnimation copy];
pathAnimation.keyPath = @"path";
// The path property has not been updated to the new value yet
pathAnimation.fromValue = (id)self.path;
// …Run Code Online (Sandbox Code Playgroud) 我总是使用CoreGraphics和CoreAnimation,我理解他们每个人如何自己工作,但不是那些必须与另一个人交谈时的边缘情况.我也明白UIViews是一个很好的包装器CALayer,CALayer渲染的所有重要部分,以及UIView基于触摸的响应性增加.
但是,到目前为止我所看到的所有问题都是从一方或另一方面解决问题,而不是它们之间的相互作用,特别是在CoreGraphics和CALayer.之间.
无论如何,我的问题是......
我的理解是,CALayer包装CoreGraphics方法来绘制自己,但是只执行一次,并且可以使用自身的快照直到无效.但是,这些绘图方法如何与该层的子图层相互作用?它们是独家的吗?
例如,当我有一个UIView具有子视图的情况时会发生什么,并且我重载了该drawRect方法?这对它的子图层的绘制有何影响?
将两者混合在同一个函数中是不是一个好主意?
另外,我只询问iOS,我知道Mac是一个不同的野兽(也有那些花哨的CIFilters,混蛋!).
以下是我事先研究过的一些相关问题:
我有一个图像和一组四个点(描述四边形Q).我想转换这个图像,使其适合四边形Q.Photoshop称这种转换为"扭曲".但是根据这个四边形的来源(图像在空间中移动的视角),它实际上是尺度,旋转和透视矩阵的组合.
我想知道使用CATransform3D 4x4矩阵是否可行.你有任何关于如何做到这一点的提示吗?我试图取四个点并构建16个方程式(A'= A xu),但它不起作用:我不确定我应该使用什么作为z,z',w和w'系数......
下图显示了我想要做的事情:

以下是一些要点的例子:
276.523, 236.438, 517.656, 208.945, 275.984, 331.285, 502.23, 292.344
261.441, 235.059, 515.09, 211.5, 263.555, 327.066, 500.734, 295
229.031, 161.277, 427.125, 192.562, 229.16, 226, 416.48, 256
Run Code Online (Sandbox Code Playgroud) 我遇到以下警告问题:
CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯.
我正在使用NSOperation对象来执行一些计算,一旦完成,它会将消息发送回AppDelegate,然后隐藏进度条并取消隐藏某些按钮.如果我将消息注释回AppDelegate,则警告消失,但进度条显然仍然可见且动画.
我正在使用xCode 4.4.1和OSX 10.8.1,但是,当我在OSX 10.7.4上使用相同版本的xCode编译和运行代码时,我没有收到警告,代码按预期运行.
设置CA_DEBUG_TRANSACTIONS = 1环境变量会将回溯显示为来自AppDelegate中的NSControl setEnabled消息.
答案可能是盯着我看,但也许我喝的咖啡太多了!
QuartzCore .layer.shadow吸收了性能.它们似乎需要在每次发生变化时重新渲染,导致一切都滞后.
Coregraphics渐变(用于单向阴影) - 看起来不正确.如果你的渐变从0.3 alpha变为0,它会产生一些奇怪的效果,你可以"看到"它停止.它看起来不漂亮或自然.也许它没有抖动,但我确信我听说过核心图形渐变.这很奇怪,我不知道.
Coregraphics阴影 - 在设置时需要一段时间来渲染,但其他方面性能很好.只是第二个你正在等待视图出现,因为它必须先渲染它的阴影,这就是问题所在.
所以我一定错过了什么.还有另一种看起来正确的方法,并且在渲染时间和性能方面都很快吗?
我试图设置持续时间(使用我将尝试的常规方法)来设置UICollectionView的selectItemAtIndexPath:animated:scrollPosition:方法(或scrollToItemAtIndexPath:atScrollPosition:animated:方法)的动画持续时间.我试过了[UIView setAnimationDuration],我试过将它包装成一个CATransaction.在改变动画持续时间方面,我一直没有成功(尽管我承认我可能在这个逻辑中犯了一个错误).
思考?
更新:
我在这里尝试了很多方法.最接近的解决方案是执行我们通常对UIScrollView动画执行的操作(通过将animated:参数设置为NO并将其包装在UIView动画块中).这适用于scrollview.但是,这个螺丝与UICollectionView创作过程有某些原因.
我在下面使用两种方法包含了一个示例.每种方法都假设您有4个部分,每个部分有4个项目.此外,动画假设您从0,0移动到3,3.
使用默认动画
这里的部分问题肯定与此有关UICollectionView.如果您采用以下方法(使用默认动画选项) - 一切正常:
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:3 inSection:3]
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:YES];
Run Code Online (Sandbox Code Playgroud)
执行此操作时,将创建当前可见单元格与目标单元格之间的每个单元格.我已经包含了登录collectionView:cellForItemAtIndexPath:方法:
2013-05-18 09:33:24.366 DEF-CV-Testing[75463:c07] Transition
Cell Created for Index Path: <NSIndexPath 0x8913f40> 2 indexes [0, 1]
Cell Created for Index Path: <NSIndexPath 0x75112e0> 2 indexes [0, 2]
Cell Created for Index Path: <NSIndexPath 0xfe1a6c0> 2 indexes [0, 3]
Cell Created for Index Path: <NSIndexPath …Run Code Online (Sandbox Code Playgroud) 目的
我试图使用从字形生成的UIBezierPath创建人类书写的动画近似.我理解并且我已经阅读了许多与我的相似的UIBezierPath问题(但不一样).我的目标是创建一个近似于执行字符和字母书写的人的外观的动画.
背景
我创建了一个游乐场,用于更好地理解用于动画字形的路径,就好像它们是手工绘制的一样.
Apple CAShapeLayer中的一些概念(strokeStart和strokeEnd)在动画时似乎并没有按预期运行.我认为通常人们倾向于将中风想象成使用书写工具(基本上是直线或曲线).我们认为笔划和填充是一条线,因为我们的书写工具不区分笔画和填充.
但是当动画时,路径的轮廓由线段构成(填充是单独处理的,不清楚如何设置填充位置的动画?).我想要实现的是一个自然的人类书写线/曲线,它显示了一个笔划的开始和结束,以及当动画从头到尾移动时添加的部分.最初看起来很简单,但我认为它可能需要设置填充位置的动画(不确定如何执行此操作),笔划开始/结束(不确定是否需要根据上面提到的动画执行方式的意外警告),以及使用子路径(如何从已知路径重建).
方法1
所以,我考虑过Path(CGPath/UIBezierPath)的想法.每个路径实际上包含构造字形所需的所有子路径,因此可能递归这些子路径并使用CAKeyframeAnimation/CABasicAnimations和显示部分构造的子路径的动画组将是一个很好的方法(尽管每个子路径的填充位置和笔划仍然是需要从头到尾动画?).
这种方法导致了一个精炼的问题:
如果有一个完整的UIBezierPath/CGPath,如何访问和创建UIBezierPath/CGPath(子路径)?
如何使用路径/子路径信息用书写工具绘制填充和描边的动画?(似乎这意味着需要同时为CALayer的strokeStart/strokeEnd,position和path属性设置动画)
注意:
正如人们可以在代码中观察到的那样,我确实拥有从字形获得的完成路径.我可以看到路径描述给了我类似路径的信息.如何获取该信息并将其重新编排为一组数据子路径 人类可写的笔画?
(这里的想法是将点信息转换为人类笔画的新数据类型.这意味着要求算法识别每个填充的起点,斜率,端点和边界)
提示
我在Pleco(一个成功实现类似算法的iOS应用程序)中注意到,每个笔划都由描述人类可写笔画的闭合路径组成.UIBezierPath具有基于连续填充填充的封闭路径.需要一种算法来细化重叠填充以为每个笔画类型创建不同的闭合路径.
Erica Sadun 在github上提供了一组路径实用程序.我没有完全探索这些文件,但它们可能在确定离散笔划时非常有用.
UIBezierPath结构似乎基于连续线段/曲线的概念.在填充的交叉点处出现汇合点,其表示有向路径变化.可以计算曲线/线段的行程/填充角度,并搜索相应汇流点的其他曲线/线吗?(即将一条线段连接在相交填充的间隙上,以产生两条独立的路径 - 假设一条线路拾取了点,并使用新的线段/曲线重新创建了路径)
内省:是否有更简单的方法?我错过了一个关键的API,一本书或更好的方法来解决这个问题吗?
一些替代方法(无用 - 需要加载GIF或闪存)以产生所需的结果:
良好的示例(使用Flash),其中一个表示层显示书写笔划的进展.(如果可能的话,这就是我想要在Swift/iOS中近似的东西) - (alt链接 - 请参阅左边的动画图像)
一个不太好的例子,显示使用渐进路径和填充来近似书写笔划特征(动画不流畅且需要外部资源):

一个Flash版本 - 我熟悉创建Flash动画,但我不愿意在1000版本中实现这些功能(不要太提及它在iOS上不受支持,尽管我可能还可以转换算法以利用带有css动画的HTML5画布).但是这个思路似乎有点远,毕竟,我想要的路径信息存储在我从提供的字体/字符串中提取的字形中.
方法2
我正在考虑使用基于笔划的字体而不是基于轮廓的字体来获取正确的路径信息(即填充表示为路径的信息).如果成功,这种方法比近似笔画,笔画类型,交叉点和笔画顺序更清晰.我已经向Apple提交了雷达,建议将基于笔划的字体添加到iOS(#20426819).尽管有这些努力,我仍然没有放弃形成一种算法,该算法解决了贝塞尔曲线上的线段和曲线的部分笔划,全笔画,交叉点和汇合点.
基于讨论/答案的最新想法
根据以下任何正在进行的对话和答案,提供以下附加信息.
笔划顺序很重要,大多数语言(本例中为中文)都有明确定义的笔划类型和笔划顺序规则,它们似乎提供了一种机制,可根据每个CGPathElement提供的点信息确定类型和顺序.
CGPathApply和CGPathApplierFunction看起来很有希望作为枚举子路径的方法(保存到数组并应用填充动画)
可以将一个蒙版应用于图层以显示子图层的一部分(我之前没有使用过此属性,但看起来如果我可以在子路径上移动可能有助于填充动画的蒙版图层?)
为每个路径定义了大量的点.好像仅使用字形轮廓定义BezierPath.这一事实使得理解交叉填充的开始,结束和结合是消除特定填充的歧义的重要因素.
可以使用其他外部库,以便更好地解决笔划行为.其他技术如Saffron Type System或其衍生产品之一可能适用于此问题域.
仅仅为动画设置动画的最简单解决方案的基本问题是可用的iOS字体是轮廓字体而不是基于笔划的字体.一些商业制造商确实生产基于笔划的字体.如果你有其中一个用于测试,请随意使用操场文件的链接.
我认为这是一个常见问题,随着我向解决方案迈进,我将继续更新帖子.如果需要进一步的信息或者我可能遗漏了一些必要的概念,请在评论中告诉我.

可能解决方案
我一直在寻找最简单的解决方案.问题源于字体的结构是轮廓字体而不是基于笔画的字体.我发现了一个基于笔划的字体样本进行测试,并使用它来评估概念证明(见视频).我现在正在寻找扩展的单笔划字体(包括中文字符)以进一步评估.一个不太简单的解决方案可能是找到一种方法来创建一个跟随填充的笔划,然后使用简单的二维几何来评估首先设置动画的笔划(例如中文规则在笔划顺序上非常清晰). …
我想动画从子视图到超级视图的过渡.
我使用以下方式显示子视图:
[UIView beginAnimations:@"curlup" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[self.view addSubview:self.mysubview.view];
[UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)
以上工作正常.它回到超级视图,我没有得到任何动画:
[UIView beginAnimations:@"curldown" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[self.view removeFromSuperview];
[UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)
我有什么不同的东西可以让子视图在移除时动画化吗?
我们目前正在开发一个包含一系列图标的应用程序.我们希望图标在按下时像应用程序删除动画一样摆动.编码这个动画序列的最佳方法是什么?
我有一个CAKeyframeAnimation动画,我想永远重复使用repeatCount = HUGE_VALF.动画的持续时间是2秒,但我想在每个周期之前暂停3秒.
我能想到的唯一两种方法是:
使整个动画持续5秒,并添加额外的keyTimes和值,以便在5s动画的最后3s中获得我正在寻找的暂停.这感觉有点哈哈.
让动画只重复一次然后添加使用类似于performSelector:afterDelay:2再次运行动画,等等.这也很脏.也意味着我需要addAnimation:每5秒调用一次,我不确定它在性能方面是否是最佳的.
还有其他选择我可能会失踪吗?这两种方法中哪一种比另一种更好?
core-animation ×10
ios ×8
iphone ×5
cocoa-touch ×2
objective-c ×2
animation ×1
cashapelayer ×1
cgpath ×1
math ×1
nsoperation ×1
shadow ×1
swift ×1
uibezierpath ×1
uiview ×1