UITableViewCell skipped in responder chain

怎甘沉沦 提交于 2019-11-30 03:52:25
nschmidt

The cell seems to ask its table view for permission. To change that you can of course override

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    return [self respondsToSelector:action];
}

Swift 3, 4, 5:

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return self.responds(to: action)
}

I've concluded that this is either a bug or undocumented intended behavior. At any rate, I ended up brute force fixing it by responding to the event in a subview and then manually propagating the message up the responder chain. Something like:

- (void)customEventFired:(id)sender {
  UIResponder *nextResponder = self.nextResponder;
  while (nextResponder) {
    if ([nextResponder respondsToSelector:@selector(customEventFired:)]) {
      [nextResponder performSelector:@selector(customEventFired:) withObject:sender];
      break;
    }
    nextResponder = nextResponder.nextResponder;
  }
}

I've also updated my demo project to show how I'm using this "fix" https://github.com/keithnorm/ResponderChainTest.

I still welcome any other ideas if anyone else figures this out, but this is the best I've got for now.

You can change the code in View.m as

      [button addTarget:nil action:@selector(customEventFired:) forControlEvents:(1 << 24)];

to

      [button addTarget:cell action:@selector(customEventFired:) forControlEvents:(1 << 24)];

do like this

    @implementation ContentView

   // uncomment this to see event caught by the cell's subview

  - (id)initWithFrame:(CGRect)frame
 {
     self = [super initWithFrame:frame];
    if(self)
   {

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setTitle:@"Click" forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor blueColor]];
    [button addTarget:self action:@selector(customEventFired:) forControlEvents:UIControlEventTouchUpInside];
    button.frame = CGRectMake(4, 5, 100, 44);
    [self addSubview:button];
  }

    return self;
}

 - (void)customEventFired:(id)sender
{
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Event Triggered in cell subview" message:@"so far so good..." delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
    [alertView show];
 }

@end

now customEventFired: method get called

I think this one is the easiest solution. If you do not specify a target the event will automatically bubble up the responder chain.

[[UIApplication sharedApplication]sendAction:@selector(customAction:) to:nil from:self forEvent:UIEventTypeTouches];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!