像Tweetie一样滑动显示菜单

时间:2010-07-07 21:59:15

标签: iphone uitableview core-animation cabasicanimation

我一直在开发一个新的应用程序,并且真的希望实现一次滑动以在我的应用程序中显示更多选项菜单。我进行了搜索和搜索,但似乎没有其他人成功地使其工作(除了Loren)。我要做的是滑动单元格,同时使用CABasicAnimation将其推送到x:320,并在此下面添加一个子视图,其中包含按钮等。我正在使用willBeginEditing来检测滑动以避免子类化。这是代码:

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {

 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

 CABasicAnimation *theAnimation;          

 theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

 theAnimation.duration=0.0;

 theAnimation.repeatCount=0;

 theAnimation.autoreverses=NO;

 theAnimation.removedOnCompletion = NO;

 theAnimation.fillMode = kCAFillModeForwards;

 theAnimation.fromValue=[NSNumber numberWithFloat:0];

 theAnimation.toValue=[NSNumber numberWithFloat:+320];

 [cell.layer addAnimation:theAnimation forKey:@"animateLayer"];

 CGRect frame = CGRectMake(0, 59 * indexPath.row, 320, 59);

 UIView *menu = [[[UIView alloc] initWithFrame:frame] autorelease];


 NSString *path = [NSString stringWithFormat:@"%@%@",

                       [[NSBundle mainBundle] resourcePath],

                       @"/flick.wav"];



 SystemSoundID soundID;

 NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];

 AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);

 AudioServicesPlaySystemSound(soundID);

 self.menu.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dots.png"]];

 [self.view addSubview:menu];

 [self.view sendSubviewToBack:menu];

 }



- (void)animationDidStop:(NSString*)animationID finished:(BOOL)finished context:(void     *)context 

{

   // Release

   [self release];

}


 #pragma mark - Swipe Menu II



- (void)scrollViewDidScroll:(UIScrollView *)tableView {

     UITableViewCell *cell = [tableView cellForRowAtIndexPath:nil];

     CABasicAnimation *theAnimation;          

     theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

     theAnimation.duration=0.2;

 theAnimation.repeatCount=0;

 theAnimation.autoreverses=NO;

 theAnimation.fromValue=[NSNumber numberWithFloat:320];

 theAnimation.toValue=[NSNumber numberWithFloat:0]

 ;

 [cell.layer addAnimation:theAnimation forKey:@"animateLayer"];

 }

问题是单元格的向后滑动 - 我想在收到菜单视图外的任何触摸时这样做,但因为它是一个scrollView,我不能。 ScrollViewdidScroll方法仅在滚动视口后将单元格动画回其正常位置。 (如在NavigationBar或隐藏它的对象下)最后一个关键问题是能够检测菜单是否已经可见或活动且单元格已经离开屏幕,将单元格滑回原始位置,删除菜单视图,然后滑出另一个单元格并添加菜单。

我希望成为第一个与Loren一起实现此功能的人,就像许多其他人一样,特别是在StackOverflow上。

我为代码中的格式不佳道歉。

提前致谢, 歌林

2 个答案:

答案 0 :(得分:6)

我实际上做得很好,你可以在这里查看项目:http://www.thermoglobalnuclearwar.com/opensource/

它还克服了Tweetie中的问题,即在没有先擦除其他内容的情况下,您无法刷两次相同的单元格。

如果您做出任何建设性的更改或需要任何帮助,请告诉我们!

答案 1 :(得分:1)

Loren的实现有一个致命的缺陷,如果你在一个单元格上滑动,然后滚动表格,你不能重新刷同一个单元格,直到你刷一个不同的单元格。我相信这是因为tableview认为在您尝试“编辑”另一个单元格之前,单元格仍在编辑中。

您可能需要调查其他内容,例如使用附加到单元格的UISwipeGestureRecognizer来检测滑动。

我可以想到两种方法来尝试检测细胞外的水龙头。第一个是子类UIApplication并覆盖-sendEvent:。您可以使用它来检测点击事件并关闭单元格“编辑”。这里的主要问题是给出UIApplication子类关于你的细胞的知识。第二种方法是在整个屏幕上拍摄自定义UIView子类,在-hitTest:withEvent:中,您可以测试触摸是否属于单元格上的区域。如果没有,则关闭单元格“编辑”。在这两种情况下,返回nil以允许事件继续进行基础视图(并且不要忘记在事件发生后删除此覆盖视图)。您可能还想测试UIEvent,以确保它在解除单元格之前包含新的触摸。