我正在编写一个iOS 5应用程序(在Xcode 4.3中,使用Storyboards和ARC),该应用程序具有一些需要响应水平平移的表格单元格。我有一个工作非常好的表设置,但后来我需要在另一个场景中实现相同的行为。我认为最佳实践方法是将手势识别和处理代码抽象为子类。但现在tableView无法滚动,我在旧方法下解决这个问题的方法也无济于事。
我有一个RestaurantViewController
,它继承自UIViewController
并具有属性ULPanningTableView *tableView
。该表的某些单元格是MenuItemCell
,并继承自ULPanningTableViewCell
。表的委托和数据源是RestaurantViewController
。
ULPanningTableViewCell
继承自UITableViewCell
,与原来的非常接近,唯一的区别是它具有跟踪单元格的前视图和后视图以及自定义背景的属性。
ULPanningTableView
有点复杂,因为它必须设置识别和处理。
ULPanningTableView.h
:
#import <UIKit/UIKit.h>
@interface ULPanningTableView : UITableView <UIGestureRecognizerDelegate>
@property (nonatomic) float openCellLastTX;
@property (nonatomic, strong) NSIndexPath *openCellIndexPath;
- (id)dequeueReusablePanningCellWithIdentifier:(NSString *)identifier;
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer;
// ... some helpers for handlePan:
@end
和ULPanningTableView.m
:
#import "ULPanningTableView.h"
#import "ULPanningTableViewCell.h"
@implementation ULPanningTableView
@synthesize openCellIndexPath=_openCellIndexPath, openCellLastTX=_openCellLastTX;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#pragma mark - Table View Helpers
- (id)dequeueReusablePanningCellWithIdentifier:(NSString *)identifier
{
ULPanningTableViewCell *cell = (ULPanningTableViewCell *)[self dequeueReusableCellWithIdentifier:identifier];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGestureRecognizer setDelegate:self];
[cell addGestureRecognizer:panGestureRecognizer];
return cell;
}
#pragma mark - UIGestureRecognizerDelegate protocol
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// for testing: only allow UIScrollViewPanGestureRecognizers to begin
NSString *gr = NSStringFromClass([gestureRecognizer class]);
if ([gr isEqualToString:@"UIScrollViewPanGestureRecognizer"]) {
return YES;
} else {
return NO;
}
}
#pragma mark - panhandling
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer
{
// ...
}
// ... some helpers for handlePan:
@end
我曾经尝试过gestureRecognizerShouldBegin:
,因为当它们不是单独的类时,这就是我解决这个问题的方法(ULPanningTableView
的东西在RestaurantViewController
中实现,ULPanningTableViewCell
的东西是在MenuItemCell
中实现的。对于translationInView
更垂直而不是水平的手势,我基本上会返回NO)。无论如何,我无法滚动表格!如果我从gestureRecognizerShouldBegin:
返回YES,或者如果我完全删除UIGestureRecognizerDelegate
实现,我可以识别平移手势。
我还是iOS和Objective-C的初学者,所以我只是根据我读过的东西有预感,而且我从一个类似的问题中得到的印象是,罪魁祸首是UIScrollViewPanGestureRecognizer
用响应链做巫毒。。。
我将非常感谢你能提供的任何线索!
好吧,所以我觉得真的很傻。-handlePan:
已经是一个方法了!我把它改成了-handleCustomPan:
,它可以正常处理其他锅。我不知道为什么它没有崩溃,但它确实崩溃了。哦,我不得不把UIScrollViewPanGestureRecognizer边缘案例保存在-gestureRecognizerDidBegin:
:中
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
NSString *gr = NSStringFromClass([gestureRecognizer class]);
if ([gr isEqualToString:@"UIScrollViewPanGestureRecognizer"]) {
// allow scroll to begin
return YES;
} else if ([gr isEqualToString:@"UIPanGestureRecognizer"]){
UIPanGestureRecognizer *panGR = (UIPanGestureRecognizer *)gestureRecognizer;
// allow horizontal pans to begin
ULPanningTableViewCell *cell = (ULPanningTableViewCell *)[panGR view];
CGPoint translation = [panGR translationInView:[cell superview]];
BOOL should = (fabs(translation.x) / fabs(translation.y) > 1) ? YES : NO;
if (!should) {
[self closeOpenCellAnimated:YES];
}
return should;
} else {
NSLog(@"%@",gestureRecognizer);
return NO;
}
}