如果忽略"UIGestureRecognizerDelegate"的重复协议定义,如何定义目标 [英] if Duplicate protocol definition of 'UIGestureRecognizerDelegate' is ignored how can I define targets
问题描述
更新2
即使问题仍然存在,当前形式的问题也已得到回答和接受. 该代码现在以0个警告进行编译,但仍然对手势无响应.解决问题后,将希望通过准备新问题的过程来更新代码. 此处.
The question in its current form has been answered and accepted even though a problem remains viz. the code now compiles with 0 warnings but still remains unresponsive to gestures. Code will be updated once the problem is solved, hopefully, through the process of preparing a new question. A new question has been posted here.
据我所知,在我读过的任何一篇文章中都从未问过或回答过这个问题(请参见下面的 重复项).
As far as I know this question has never been asked or answered in any post I have read (see possible duplicates below).
我正在尝试编写Objective C测试代码,以便从iPhone屏幕上由矩形UIView
定义的任何区域中长按,点击或移动消息.到目前为止,如果UIView
和处理程序方法都位于UIViewController
中,则我可以使用UILongPressGesture,
UITapGesture
或UIPanGesture
可靠地发送离散或连续消息.
I am trying to write Objective C test code to send either long press, tap or pan messages from any area defined by a rectangular UIView
on an iPhone screen. So far I can send discrete or continuous messages reliably using either UILongPressGesture,
UITapGesture
or UIPanGesture
if both UIView
and handler methods are located in the UIViewController
.
最终,我想将手势消息从几个子类化的UIViews
发送到UIViewController
中的常用处理程序,但是在尝试执行此操作时遇到了问题.在编写代码时,我研究了有关使用UIGestureRecognition的委托和 Touches 中的Objective C方法(请参阅以下注意事项)中的Objective C方法的Apple文档以及在SO帖子中找到的示例(下面的链接).
Ultimately I want to send gesture messages from several subclassed UIViews
to common handlers in the UIViewController
but I hit problems when I tried to do it. While writing the code I studied an Apple document on using delegates for UIGestureRecognition together with Objective C methods in Touches (see Note below) and examples found in SO posts (Links below).
该代码无法响应手势输入.最初,它编译时包含四个警告和两个问题:
The code fails to respond to gestural input. Initially it compiled with four warnings and two issues:
- 重复协议
"UIGestureRecognizerDelegate"的重复协议定义为 已忽略
Duplicate protocol definition of 'UIGestureRecognizerDelegate' is ignored
更新1
现在已解决此问题. Paul的答案阐明了到目前为止我还不了解的观点.作为回应,我在本文中更改了协议的名称,测试了代码并对其进行了更新.
This has now been addressed. Paul’s answer clarifies a point I hadn’t understood until now. In response I changed the name of the protocol, tested the code and updated it in this post.
在OneOfSeveralSubviews.h
中,该协议现在称为FirstGestureRecognizerDelegate.
,例如,在ViewController
中已进行了相关更改.
In OneOfSeveralSubviews.h
the protocol is now called FirstGestureRecognizerDelegate.
Relevant changes have been made in the ViewController
e.g.
@interface ViewController : UIViewController <FirstSubviewGestureDelegate, SecondSubviewGestureDelegate>
- 未声明的选择器.
通过设置代表属性来静音三个警告-即插入id
(根据建议插入 here )-对三个手势声明(即initWithTarget:(id)self
)进行了类似的更改,并在self
的每个实例中添加了一个委托属性,以便将消息发送到预期的目标-即(id)self.delegate
代替(id)self
Three warnings were silenced by making the delegate property typed - i.e. inserting id
(as recommended here) - with similar changes made to the three gesture declarations - i.e. initWithTarget:(id)self
- with a delegate property added to each instance of self
so messages are sent to intended targets - i.e. (id)self.delegate
instead of (id)self
该代码先前编译时带有一个警告,但对手势无响应.
The code previously compiled with one warning but remained unresponsive to gestures.
更新2
该代码现在以0个警告进行编译,但仍然对手势无响应.
The code now compiles with 0 warnings but still remains unresponsive to gestures.
我对照列出的四个点检查了代码 此处 (即userInteractionEnabled
,minimumPressDuration
,numberOfTapsRequired
和numberOfTouchesRequired
),并确保在UIViewController.h.
I checked the code against the four points listed here (i.e. userInteractionEnabled
, minimumPressDuration
, numberOfTapsRequired
and numberOfTouchesRequired
) and made sure to specify the delegate in UIViewController.h.
我的第一个初始问题已经回答
The first of my initial questions has already been answered
Q.1接口中的协议定义是duplicate
吗?
这两个问题有待回答
Q.2如果默认情况下已经存在UIGestureRecognizer协议,那么我如何定义将处理手势消息的目标?或
Q.2 if the UIGestureRecognizer protocol is already there by default, then how do I define the targets that will handle the gesture messages ? or
Q.3如何定义不是self
而是ViewController中的方法的委托目标?
Q.3 how do I define a delegate target that is not self
but rather a method within the ViewController ?
我相信,有更多经验的人可以认出答案并解释我未做的事情,或者提出一些问题的答案,以进一步阐明问题.谢谢您的期待.
I'm confident someone with more experience can recognise the answers and explain what I haven't done or suggest questions that shed more light on the problem. Thanks in anticipation.
图文并茂的解释也将使那些需要学习更多有关委托人的知识的人受益,这需要对代理人有更多了解-有些人掌握了旧知识,但仍然赶不上黑客入侵的前沿领域(如我:-).
An illustrated explanation would also benefit those working in Objective C who need to learn more about delegates - old knowledge for some but still a frontier for hacks (like me :-) trying to catch up.
格雷格
更新2
如果从handleTap:
手势声明中删除了.delegate
属性,并点击了红色方块,则程序将崩溃,并显示以下日志:
If the .delegate
property is removed from the handleTap:
gesture declaration and the red square is tapped, the program will crash with the following log:
[OneOfSeveralSubviews handleTapSelect:] : unrecognized selector sent to instance 0x7fbe27d064b0
如果还将.delegate
属性从handleLongPress:
或handlePan:
手势声明中删除,也会出现类似的崩溃日志.
A similar crash log appears if the .delegate
property is also removed from the handleLongPress:
or handlePan:
gesture declaration.
代码的第一部分是ViewController(在下面的 ),其中包含称为(1) handleLongPress:
(2)的三个目标方法. em> handleTapSelect:
和(3) handlePan:
The first part of the code is the ViewController (below) which contains the three target methods called (1) handleLongPress:
(2) handleTapSelect:
and (3) handlePan:
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
OneOfSeveralSubviews *oneForAll=[[OneOfSeveralSubviews alloc] initView:[UIScreen mainScreen].bounds];
[self.view addSubview:oneForAll];
}
(方法1 )
- (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");
}
(方法2)
- (void)handleTapSelect:(id)sender
{
NSLog(@"tapped");
}
(方法3 )
- (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;
}
}
ViewController.h
#import <UIKit/UIKit.h>
#import "OneOfSeveralSubviews.h"
@interface ViewController : UIViewController <FirstSubviewGestureDelegate, SecondSubviewGestureDelegate>
{
CGRect touchFrame;
}
@property (strong, nonatomic) NSTimer *timer;
@end
OneOfSeveralSubviews.m
#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
OneOfSeveralSubviews.h
#import <UIKit/UIKit.h>
@protocol FirstSubviewGestureDelegate <NSObject>
- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer;
- (void)handleTapSelect:(UITapGestureRecognizer*)gestureRecognizer;
- (void)handlePan:(UIPanGestureRecognizer*)gestureRecognizer;
@end
@interface OneOfSeveralSubviews : UIView
{
CGRect touchFrame;
}
- (id)initView:(CGRect)rect;
@property (assign) id<FirstSubviewGestureDelegate> delegate;
@end
链接
Links
- .delegate = self是什么意思?
- 代表和事件之间有什么区别?
- 为什么通常给Objective-C委托分配属性 而不是保留?
- 何时在Objective-c中使用responsesToSelector
- 目标C响应选择器
- iOS-UILongPressGestureRecognizer
- 使用UILongPressGestureRecognizer和UISwipeGestureRecognizer
- 将UILongPressGestureRecognizer用于UIScrollview的子视图
- What is meant by .delegate=self?
- What are the differences between delegates and events ?
- Why are Objective-C delegates usually given the property assign instead of retain?
- when to use respondsToSelector in objective-c
- Objective C responds to selector
- iOS - UILongPressGestureRecognizer
- Using UILongPressGestureRecognizer and UISwipeGestureRecognizer
- Using UILongPressGestureRecognizer For Subviews of UIScrollview
可能重复
possible duplicates
- Duplicate protocol definition warning, but I need multiples of this
protocol - warning: duplicate protocol definition of '…' is ignored
- Duplicate protocol definition
Duplicate protocol definition warning
注意
Note
The Apple document on handling gestures includes examples in Swift. If you work in Objective C refer to Touches but bear in mind that it no longer compiles on versions "earlier than iOS 7". If you are able to provide a more useful reference for Objective C programmers please edit this note.
推荐答案
UIGestureRecognizerDelegate
由UIKit声明.您不能创建自己的名为UIGestureRecognizerDelegate
的协议.这是一个相互矛盾的声明.
UIGestureRecognizerDelegate
is declared by UIKit. You can't create your own protocol named UIGestureRecognizerDelegate
; it is a conflicting declaration.
按照惯例,以 UI 为前缀的类和协议由UIKit声明,并且您不应使用此前缀声明自己的对象和类.使用类似MyGestureRecognizerDelegate
By convention, classes and protocols prefixed with UI are declared by UIKit and you should not declare your own objects and classes with this prefix. Use something like MyGestureRecognizerDelegate
这篇关于如果忽略"UIGestureRecognizerDelegate"的重复协议定义,如何定义目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!