如果重复的协议定义为' UIGestureRecognizerDelegate'被忽略我如何定义目标

时间:2018-03-12 23:52:02

标签: ios objective-c delegates uigesturerecognizer

更新2

即使问题仍然存在,目前形式的问题已得到回答和接受。 代码现在编译0警告但仍然无法响应手势。一旦问题得到解决,希望通过准备新问题的过程更新代码。已发布一个新问题here

据我所知,这个问题从未在我读过的任何帖子中被询问或回答(参见下面可能的重复)。

我正在尝试编写Objective C测试代码,以便从iPhone屏幕上的矩形UIView定义的任何区域发送长按,点击或平移消息。到目前为止,如果UILongPressGesture,和处理程序方法都位于UITapGesture,我可以使用UIPanGesture UIViewUIViewController可靠地发送离散或连续消息。

最终,我想将几​​个子类UIViews的手势消息发送到UIViewController中的常见处理程序,但是当我尝试执行此操作时遇到了问题。在编写代码时,我研究了一个Apple文档,其中使用了UIGestureRecognition的委托和 Touches 中的Objective C方法(参见下面的注释)和SO帖子中的示例(以下链接)。

代码无法响应手势输入。最初它编译了四个警告和两个问题:

  1. 重复协议
  2.   

    ' UIGestureRecognizerDelegate'重复的协议定义是   忽略

    更新1

    现在已经解决了这个问题。 Paul’s answer澄清了我迄今尚未理解的一点。作为回应,我更改了协议的名称,测试了代码并在此帖子中更新了它。

    OneOfSeveralSubviews.h中,现在调用协议FirstGestureRecognizerDelegate.已在ViewController中进行了相关更改,例如

    @interface ViewController : UIViewController <FirstSubviewGestureDelegate, SecondSubviewGestureDelegate>
    
    1. 未宣布的选择器。
    2. 通过输入委托属性来沉默三个警告 - 即插入id作为推荐的 here) - 对三个手势声明进行了类似的更改 - 即{ {1}} - 在initWithTarget:(id)self的每个实例中添加了委托属性,以便将消息发送到预定目标 - 即self而不是(id)self.delegate

      以前使用一个警告编译但仍未对手势反应的代码。

      更新2

      现在代码编译0警告但仍然没有响应手势。

      我针对列出 here 的四个点检查了代码(即(id)selfuserInteractionEnabledminimumPressDurationnumberOfTapsRequired)并确保在numberOfTouchesRequired

      中指定代理人

      我的第一个问题已经得到解答

      Q.1界面中的协议定义如何UIViewController.h.

      这两个问题尚未得到解答

      Q.2如果默认情况下UIGestureRecognizer协议已存在,那么如何定义将处理手势消息的目标?或

      问题3如何定义不是duplicate的委托目标,而是定义ViewController中的方法?

      我相信拥有更多经验的人可以认识到答案,并解释我没有做过的事情,或者提出可以解决问题的问题。谢谢你的期待。

      图解说明也有利于那些在目标C中工作的人,他们需要了解更多关于代表的知识 - 对于某些人而言仍旧的知识,但仍然是黑客(比如我:-)试图赶上的前沿。

      格雷格

      更新2

      如果从self手势声明中删除.delegate属性并点击了红色方块,程序将崩溃并显示以下日志:

      handleTap:

      如果同时从[OneOfSeveralSubviews handleTapSelect:] : unrecognized selector sent to instance 0x7fbe27d064b0.delegate手势声明中移除handleLongPress:属性,也会显示类似的崩溃日志。

      代码的第一部分是ViewController(下面),它包含三个目标方法,名为(1) handlePan: (2) handleLongPress:(3) handleTapSelect:

      ViewController.m

      handlePan:

      method 1

      #import "ViewController.h"
      
      @interface ViewController ()
      
      @end
      
      @implementation ViewController
      
      - (void)viewDidLoad {
          [super viewDidLoad];
      
          OneOfSeveralSubviews *oneForAll=[[OneOfSeveralSubviews alloc] initView:[UIScreen mainScreen].bounds];
          [self.view addSubview:oneForAll];    
      }
      

      (方法2)

      - (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer
      {
          if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
          {
              NSLog(@"started");
              self.timer=[NSTimer scheduledTimerWithTimeInterval:1.0
                                                          target:self
                                                        selector:@selector(stillPressing:)
                                                        userInfo:nil
                                                         repeats:YES];
          } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
          {
              [self.timer invalidate];
              self.timer = nil;
              NSLog(@"ended");
          }
      }
      
          - (void)stillPressing:(NSTimer *)timer
          {
              NSLog(@"pressing");
          }
      

      method 3

      - (void)handleTapSelect:(id)sender
      {
          NSLog(@"tapped");
      }
      

      ViewController.h

       - (void)handlePan:(UIPanGestureRecognizer*)gestureRecognizer
      {
          [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
      
          UIView *piece = [gestureRecognizer view];
      
          if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
              CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
      
              [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y + translation.y)];
              [gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
      
              NSLog(@"%f %f", translation.x, translation.y);
      
              [UIView animateWithDuration:0.75
                                    delay:0
                   usingSpringWithDamping:0.75
                    initialSpringVelocity:0
                                  options:UIViewAnimationOptionCurveLinear
                               animations:^{
      
                                piece.frame = touchFrame;
                            }
                                  completion:^(BOOL finished) {
                           }];
          }
      }
      
      
      - (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
      {
          if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
              UIView *piece = gestureRecognizer.view;
              CGPoint locationInView = [gestureRecognizer locationInView:piece];
              CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
      
              piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
              piece.center = locationInSuperview;
          }
      }
      

      OneOfSeveralSubviews.m

      #import <UIKit/UIKit.h>
      #import "OneOfSeveralSubviews.h"
      
      @interface ViewController : UIViewController <FirstSubviewGestureDelegate, SecondSubviewGestureDelegate>
      {
          CGRect touchFrame;
      }
      
      @property (strong, nonatomic) NSTimer *timer;
      
      @end
      

      OneOfSeveralSubviews.h

      #import "OneOfSeveralSubviews.h"
      
      @implementation OneOfSeveralSubviews
      
      - (id)initView:(CGRect)rect
      {
          self = [super initWithFrame:rect];
          if (self)
          {
              CGFloat width = [UIScreen mainScreen].bounds.size.width;
              CGFloat height = [UIScreen mainScreen].bounds.size.height;
              CGPoint screenCentre = CGPointMake(width*0.5, height*0.5);
      
              CGFloat fullSide = width * 0.33;
              CGFloat halfSide = fullSide * 0.5;
      
              touchFrame = CGRectMake(screenCentre.x - halfSide, screenCentre.y - halfSide, fullSide, fullSide);
              UIView *hotspot = [[UIView alloc] initWithFrame:touchFrame];
              hotspot.backgroundColor = [UIColor redColor];
      
              UILongPressGestureRecognizer *longPressGR = [[UILongPressGestureRecognizer alloc] initWithTarget:(id)self.delegate action:@selector(handleLongPress:)];
              [longPressGR setDelegate:(id)self.delegate];
              [longPressGR setMinimumPressDuration:0.6f];
              [longPressGR setNumberOfTapsRequired:1];
              [longPressGR setNumberOfTouchesRequired:1];
              [hotspot addGestureRecognizer:longPressGR];
      
              UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:(id)self.delegate action:@selector(handleTapSelect:)];
              [tapGR setDelegate:(id)self.delegate];
              [tapGR setNumberOfTapsRequired:1];
              [tapGR setNumberOfTouchesRequired:1];
              [hotspot addGestureRecognizer:tapGR];
              [self addSubview:hotspot];
      
              UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:(id)self.delegate action:@selector(handlePan:)];
              [panGR setDelegate:(id)self.delegate];
              [panGR setMinimumNumberOfTouches:1];
              [panGR setMaximumNumberOfTouches:1];
              [hotspot addGestureRecognizer:panGR];
      
              self.userInteractionEnabled = YES;
          }
          return self;
      }
      
      @end
      

      链接

      可能重复

      注意

      handling gestures上的Apple文档包含Swift中的示例。如果您在Objective C中工作,请参阅Touches,但请记住,它不再编译“iOS 7之前的 ”版本。如果您能够为Objective C程序员提供更有用的参考,请编辑此说明。

1 个答案:

答案 0 :(得分:3)

UIKit宣布

UIGestureRecognizerDelegate。您无法创建自己的名为UIGestureRecognizerDelegate的协议;这是一个相互矛盾的宣言。

按照惯例,UIKit声明了前缀为 UI 的类和协议,您不应该使用此前缀声明自己的对象和类。使用类似MyGestureRecognizerDelegate

的内容