解决方案:像垃圾桶动画一样

4
我想在我的程序中加入未记录的垃圾桶动画。调用方法如下:
+ (void)animateToolbarItemIndex:(unsigned)index duration:(double)duration target:(id)target didFinishSelector:(SEL)selector;

有人能够理解我应该填写什么吗:

  • 索引(index)
  • 持续时间(duration)
  • 目标(target)
  • 选择器(selector)?

我的尝试不起作用,导致出现错误:

2011-11-15 16:05:20.639 CNiPhone[973:707] +[UIToolbar animateToolbarItemIndex:duration:target:didFinishSelector:]: unrecognized selector sent to class 0x3f019c08
2011-11-15 16:05:20.641 CNiPhone[973:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[UIToolbar animateToolbarItemIndex:duration:target:didFinishSelector:]: unrecognized selector sent to class 0x3f019c08'

以下是相关代码:

@interface UIToolbar (privateMethods2)

+ (void)animateToolbarItemIndex:(unsigned)index duration:(double)duration target:(id)target didFinishSelector:(SEL)selector;

@end

    [UIToolbar animateToolbarItemIndex:0 duration:0.5 target:trashToolbarButton didFinishSelector:@selector(animateTrashStep2)];
    [UIToolbar commitAnimations];

- (void) animateTrashStep2 {
}

这是因为你不想出现在应用商店里吗? - David Dunham
是的,我明白这个方法没有文档记录。苹果的批准与我无关。 - T.J.
我相信在Stack Overflow上一定有人可以发布一个动画和图片来解决这个问题。 - T.J.
赏金评论:这个问题适用于广大受众。需要详细的规范答案来解决所有问题。我看到这个问题已经被浏览了100多次。我希望有人能发布一个垃圾桶动画和类似苹果实现的图像,可以在旨在发布到App Store的应用程序中放心使用。 - T.J.
赏金周已经结束,有一些好的想法被发布了,但仍没有完整的工作解决方案。我给所有答案点赞,因为它们都提供了一些线索,可以帮助任何想继续这个项目的人。系统将把一半的赏金授予得到最多点赞的答案。如果我在这个阶段接受任何一个答案会误导大家。当我把这个问题解决了,我会发布我的最终解决方案。 - T.J.
6个回答

3
你不需要进行任何未记录的操作,只需创建一个自定义的UIButton即可。下载UIKit Artwork Extractor,你将找到垃圾桶动画的框架,以及UIBarButtonItem的背景。

我可以在我计划提交到应用商店的项目中使用这个艺术品吗?我需要给苹果或任何图片署名吗? - T.J.
恐怕你在这里的担忧是正确的。有很多应用程序使用一些内置图像(毕竟你可以通过截屏获得图像),但在你的情况下,你使用了整个动画,因此这将完全取决于你的应用程序审核人员。不过你确实说过苹果的批准不是问题... - John Estropia
我在最初的问题中确实提到了这一点,但是当我为该问题设立赏金时,我提高了要求,即必须通过App Store审批,因为我认为这个答案将具有广泛的吸引力。 - T.J.
无论如何,这仍然是您可以使用的最安全和优雅的方法(除非您想绘制自己的图像框架)。此时指出的其他选项将使您在与苹果的审核人员打交道时陷入更多麻烦。 - John Estropia
使用艺术品提取器后,我能够通过参考http://www.grokkingcocoa.com/a-simple-way-to-animate-a-u.html使其正常工作。 - T.J.
这也是我会这样做的方式。祝您在应用商店好运! - John Estropia

3

您需要在与IBOutlet连接的工具栏上调用它,而不是在类上调用。例如:

[self.myToolbar /*(possibly just myToolbar)*/ animateToolbarItemIndex:0 duration:0.5 target:trashToolbarButton didFinishSelector:@selector(animateTrashStep2)];

我尝试过了。这是导航视图控制器的一部分,因此语句变为:[self.navigationController.toolbar animateToolbarItemIndex:0 duration:0 target:self.trashToolbarButton didFinishSelector:@selector(animateTrashStep2)]; 它不会编译并出现错误:Receiver type 'UIToolbar' for instance message does not declare a method with selector 'animateToolbarItemIndex:duration:target:didFinishSelector:'。 - T.J.
听起来你的未记录方法没有正确地被记录。换句话说,如果既不是类(如你在问题中定义的)也不是实例响应,则这不是正确的选择器。 - David Dunham
太糟糕了。这是一个不错的动画。如果有人编写了类似的代码和图像,请发布出来! - T.J.

1

我正在寻找一个更完整的答案,模仿吸气效果和垃圾桶盖的开合。 - T.J.
垃圾桶本身并不是一个真正的UIView动画,而是一组图像组合,用于模拟一个漂亮的动画。 - Christian Schnorr

1

可能是因为您的目标设置为 trashButtonItem。 目标是将didFinishSelector发送到的对象。 尝试将目标设置为self。 另外,根据http://iphonedevwiki.net/index.php/UIToolbar,这不是一个类方法,因此您需要用实际的工具栏对象替换[UIToolbar。

在您的didFinishSelector回调中,我猜您再次调用了该方法,垃圾桶会关闭。

祝你好运。


1

我认为,如果你知道如何做 suckEffect,那么你就可以用工具栏进行一点 黑客

基本上,所有官方控件都是 UIView 的子类,因此您可以找出 UIToolBar 实例的视图层次结构。

如果您不知道如何查找给定视图的子视图层次结构,则可以使用来自UIView私有 API - (void)recursiveDescription。请记得在DEBUG配置中使用它。

我们为什么要关注视图层次结构?

答案是,隐藏某些视图或添加子视图,使其符合我们的需求。

接下来是什么

  1. 找到您的垃圾桶的原始UIBarButtonItem视图
  2. 在suckEffect开始之前,隐藏它,添加一个新的垃圾桶视图,可以执行打开/关闭/摇晃的动画。此时,我认为您需要要求它执行打开动画。
  3. 然后让suckEffect飞起来...
  4. 在suckEffect结束后,要求您的视图执行关闭动画。
  5. 关闭动画完成后,删除您的视图,并重新显示原始垃圾桶视图。

可能性?

我以前没有做过,但我认为这是一种可能的解决方案,因为创建具有打开/关闭/摇晃动画的垃圾桶视图很容易。

风险?

无论如何,这个解决方案就像某种“未触及私有API的黑客攻击”,风险由您自己承担。

祝你好运。


1

这个“未记录”的方法在这里有记录:http://iphonedevwiki.net/index.php/UIToolbar

它被记录为一个实例方法而不是类方法,这解释了你在异常中收到的错误消息。

@jrtc27已经正确回答了这个问题,即应该将其发送到UIToolbar实例。从你对评论的回复来看,似乎你没有更改类别以帮助编译器。请尝试以下操作:

@interface UIToolbar (privateMethods2)
- (void)animateToolbarItemIndex:(unsigned)index duration:(double)duration target:(id)target didFinishSelector:(SEL)selector;
@end

然后使用:

[self.navigationController.toolbar animateToolbarItemIndex:0 duration:0 target:self.trashToolbarButton didFinishSelector:@selector(animateTrashStep2)];

我按照您的指示操作,程序没有报错,但是没有动画效果并且selector也没有被调用。这是我的语句:[self.navigationController.toolbar animateToolbarItemIndex:4 duration:2 target:self didFinishSelector:@selector(animateTrashStep2)]; 另外,我不知道您说的"您似乎没有将类别更改为辅助编译器"是什么意思。我该怎么做? - T.J.
(privateMethods2)是UIToolbar类的“类别”。它允许您使用新方法扩展现有类。在这种情况下,该方法已经存在,但编译器不知道它,因此它不会编译。我发布的第一个代码片段是“修复程序”。我不确定为什么它没有进行动画处理,也许索引不正确? - ikuramedia
我使用了NSLog来输出所有按钮的索引,所以我确定这点是正确的。可能需要包含一个库吗?你有能够使它动画吗? - T.J.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接