我正在编写一个iOS 5应用程序(在Xcode 4.3中,使用Storyboard和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
和{{1}内实现这些东西是在ULPanningTableViewCell
中实现的。对于MenuItemCell
比水平更垂直的手势,我基本上会返回NO。无论如何,我无法让桌子滚动!如果我从translationInView
返回YES,或者我完全删除gestureRecognizerShouldBegin:
实现,我可以让pan手势被识别。
我仍然是iOS的初学者,而且在Objective-C中,所以我只根据我读过的内容进行预感,而且我的印象来自similar problem,罪魁祸首是{ {1}}用响应者链做伏都教......
我非常感谢你能解决的任何问题!
答案 0 :(得分:0)
好的,所以我觉得很傻。 -handlePan:
已经是一种方法!我将其更改为-handleCustomPan:
,它通常会处理其他平底锅。我不确定为什么它不会崩溃,但它确实存在。哦,我必须在-gestureRecognizerDidBegin:
中保留UIScrollViewPanGestureRecognizer边缘情况:
- (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;
}
}