开发者

NavCtrl + TableViewCtrl + ScrollView, TableView not getting touches

开发者 https://www.devze.com 2023-03-17 02:14 出处:网络
I\'ve got a NavCtrl and on top of that I have a TableView/ctrl, then I have a scrollview. I\'ve got everything working, except I can\'t seem to get touches to hit the Cell\'s on the table view.

I've got a NavCtrl and on top of that I have a TableView/ctrl, then I have a scrollview.

I've got everything working, except I can't seem to get touches to hit the Cell's on the table view.

I've tried the nextResponder things and everything seems to be doing the right thing. Here's some snippets of code, keep in mind this code has been changed a lot for testing so it isn't "clean" yet :):


    ScrollView *myScrollView = [[ScrollView alloc] initWithFrame:CGRectMake(0, 150, 320, 680)];
    myScrollView.contentSize = CGSizeMake( 320 , 888);
    myScrollView.pagingEnabled = NO;
    myScrollView.bounces = NO;
    myScrollView.directionalLockEnabled = YES;
    myScrollView.canCancelContentTouches = NO;
    myScrollView.delaysContentTouches = NO;
    myScrollView.scrollEnabled = true;
    myScrollView.userInteractionEnabled = YES;
    myScrollView.scrollsToTop = NO;


     mySettingsTableView = [[SettingsTableView alloc] init];

// Settings View Ctrl
    SettingsTableViewCtrl *mySettingsTableViewCtrl = [[SettingsTableViewCtrl alloc] initWithStyle:UITableViewStyleGrouped];
    mySettingsTableViewCtrl.tableView.scrollEnabled = NO;
mySettingsTableViewCtrl.tableView.delaysContentTouches = NO;
mySettingsTableViewCtrl.tableView.canCancelContentTouches = NO;
mySettingsTableViewCtrl.view.userInteractionEnabled = YES;

[mySettingsTableViewCtrl.view addSubview:myScrollView];
[mySettingsTableViewCtrl.view addSubview:mySettingsTableView];

* In subclass of scrollView *

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    //if (![self yourMethodThatDeterminesInterestingTouches:touches withEvent:event])
    [super touchesBegan:touches withEvent:event];
    [self.nextResponder touchesBegan:touches withEvent:event];

}

Here's the NSLog from the touch events:

NSLog(@"Event: %@", event);
NSLog(@"Event NextResponder : %@\n", self.nextResponder);


2011-07-05 13:09:36.063 App[1924:14f03] Event: <UITouchesEvent: 0x802ea30> timestamp: 8503.71 touches: {(
    <UITouch: 0x80e6f60> phase: Began tap count: 1 window: <UIWindow: 0x836eb00; frame = (0 0; 320 480); layer = <CALayer: 0x836ebb0>> view: <ScrollView: 0x83770b0; baseClass = UIScrollView; frame = (0 150; 320 680); clipsToBounds = YES; layer = <CALayer: 0x8376e00>; contentOffset: {0, 0}> location in window: {140, 249} previous location in window: {140, 249} location in view: {140, 35} previous location in view: {140, 35}
)}

2011-07-05 13:09:36.065 App[1924:14f03] Event NextResponder : <SettingsTableViewCtrl: 0x8377db0>
开发者_运维百科


I have the same problem with my code, and solved it by adding UITapGestureRecognizer to the view to which I want to handle touches. In your case you should also add a UITapGestureRecognizer to either scroll view if you want to handle touches on it or table view if you want to handle touches on it as;

UITapGestureRecognizer  *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedScrollView)];
[tapRecognizer setNumberOfTapsRequired:1];
[myScrollView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];

and what you want to do on touch should be done in a method as;

-(void)tappedScrollView {
//TO-DO what you want after Scroll view touched, DO it here. }

Similarly you can do it for your table view as;

UITapGestureRecognizer  *tapRecognizerForTableView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedTableView)];
[tapRecognizerForTableView setNumberOfTapsRequired:1];
[mySettingsTableView addGestureRecognizer:tapRecognizerForTableView];
[tapRecognizerForTableView release];

and what you want to do on touch should be done in a method as;

-(void)tappedTableView { //TO-DO what you want after Table view touched, DO it here. }


Here's what I ended up, not perfect yet but working, any tuning advice would be much appreciated......

//AppDelegate.m

ScrollView *myScrollView = [[ScrollView alloc] initWithFrame:CGRectMake(0, 140, 320, 680)];
myScrollView.contentSize = CGSizeMake( 320 , 888);
myScrollView.pagingEnabled = NO;
myScrollView.bounces = NO;
myScrollView.directionalLockEnabled = YES;
myScrollView.canCancelContentTouches = NO;
myScrollView.delaysContentTouches = NO;
myScrollView.scrollEnabled = true;
myScrollView.userInteractionEnabled = YES;
myScrollView.scrollsToTop = NO;

mySettingsTableViewCtrl = [[SettingsTableViewCtrl alloc] initWithStyle:UITableViewStyleGrouped];
mySettingsTableViewCtrl.tableView.scrollEnabled = NO;
mySettingsTableViewCtrl.tableView.delaysContentTouches = NO;
mySettingsTableViewCtrl.tableView.canCancelContentTouches = NO;
mySettingsTableViewCtrl.view.userInteractionEnabled = YES;

[mySettingsTableViewCtrl.view addSubview:myScrollView];
[mySettingsTableViewCtrl.view addSubview:mySettingsTableView];

//ScrollView.m

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.nextResponder touchesBegan:touches withEvent:event];

}

//SettingsTableView.m

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [touches anyObject];
NSUInteger tapCount = [touch tapCount];
CGPoint location = [touch locationInView:self];

NSIndexPath *indexPathAtHitPoint = [self indexPathForRowAtPoint:location];
if ( [self cellForRowAtIndexPath:indexPathAtHitPoint] ) {
    [self.delegate tableView:self didSelectRowAtIndexPath:indexPathAtHitPoint];      
} else {
    [super touchesBegan:touches withEvent:event];
 }
}

Now I have a DatePicker on top of the scrollview and its working but this code needs some additional code to manage it, i.e. detect when picker is "touched" and when its not there. But that shouldn't be too difficult (I think ;)

Thanks for help and comments,

D


I think it might be overkill to use a ScrollView for your purpose. You can "scroll" any view. Position it so part or all of it is out of bounds, set clipping mode on the parent view, and when you want to "scroll" it, change its frame to in-bounds, with animation in effect. That is, if you are scrolling the DatePicker in in response to some other event (like adding an item to the table that is associated with a date). If the user scrolls the date picker in by dragging then carry on.

Combining a scroll view and a table view will be tricky, since a table view is a scroll view. It's ambiguous which should handle scrolling gestures. It might be possible but you probably have to write extra code to make the ambiguity explicit.

0

精彩评论

暂无评论...
验证码 换一张
取 消