更新2
即使问题仍然存在,目前形式的问题已得到回答和接受。 代码现在编译0警告但仍然无法响应手势。一旦问题得到解决,希望通过准备新问题的过程更新代码。已发布一个新问题here。
据我所知,这个问题从未在我读过的任何帖子中被询问或回答(参见下面可能的重复)。
我正在尝试编写Objective C测试代码,以便从iPhone屏幕上的矩形UIView
定义的任何区域发送长按,点击或平移消息。到目前为止,如果UILongPressGesture,
和处理程序方法都位于UITapGesture
,我可以使用UIPanGesture
UIView
或UIViewController
可靠地发送离散或连续消息。
最终,我想将几个子类UIViews
的手势消息发送到UIViewController
中的常见处理程序,但是当我尝试执行此操作时遇到了问题。在编写代码时,我研究了一个Apple文档,其中使用了UIGestureRecognition的委托和 Touches 中的Objective C方法(参见下面的注释)和SO帖子中的示例(以下链接)。
代码无法响应手势输入。最初它编译了四个警告和两个问题:
' UIGestureRecognizerDelegate'重复的协议定义是 忽略
更新1
现在已经解决了这个问题。 Paul’s answer澄清了我迄今尚未理解的一点。作为回应,我更改了协议的名称,测试了代码并在此帖子中更新了它。
在OneOfSeveralSubviews.h
中,现在调用协议FirstGestureRecognizerDelegate.
已在ViewController
中进行了相关更改,例如
@interface ViewController : UIViewController <FirstSubviewGestureDelegate, SecondSubviewGestureDelegate>
通过输入委托属性来沉默三个警告 - 即插入id
(作为推荐的 here) - 对三个手势声明进行了类似的更改 - 即{ {1}} - 在initWithTarget:(id)self
的每个实例中添加了委托属性,以便将消息发送到预定目标 - 即self
而不是(id)self.delegate
以前使用一个警告编译但仍未对手势反应的代码。
更新2
现在代码编译0警告但仍然没有响应手势。
我针对列出 here 的四个点检查了代码(即(id)self
,userInteractionEnabled
,minimumPressDuration
和numberOfTapsRequired
)并确保在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程序员提供更有用的参考,请编辑此说明。
答案 0 :(得分:3)
UIGestureRecognizerDelegate
。您无法创建自己的名为UIGestureRecognizerDelegate
的协议;这是一个相互矛盾的宣言。
按照惯例,UIKit声明了前缀为 UI 的类和协议,您不应该使用此前缀声明自己的对象和类。使用类似MyGestureRecognizerDelegate