I am trying to send gesture messages from several subclassed UIViews
to common handlers in a UIViewController
called TouchController.
I am using a customised protocol to address a question arising from the answer to my previous SO post.
Messages are now sent from OneOfSeveralSubviews
using a customised protocol called FirstGestureRecognizerDelegate
but none of the handlers respond even though the code compiles with 0 warnings. I am confident the problem is not in TouchController
for reasons stated previously. And after looking at more references (below) and checking out possible duplicates (below) I am now looking for answers to a new set of questions.
See Note (below) for my response to a possible duplicate question.
Here is my customised protocol
OneOfSeveralSubviews.h
#import <UIKit/UIKit.h>
@protocol FirstGestureRecognizerDelegate <NSObject>
- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer;
- (void)handleTapSelect:(UITapGestureRecognizer*)gestureRecognizer;
- (void)handlePan:(UIPanGestureRecognizer*)gestureRecognizer;
@end
@interface OneOfSeveralSubviews : UIView
{
CGRect touchFrame;
}
- (id)initView:(CGRect)rect;
@property (nonatomic, weak) id<FirstGestureRecognizerDelegate> delegate;
@end
In the implementation of OneOfSeveralSubviews,
gestures are defined by declaring instances of UILongPressGestureRecognizer
, UITapGestureRecognizer
and UIPanGestureRecognizer
and setting their delegate properties
e.g.
UILongPressGestureRecognizer *longPressGR = [[UILongPressGestureRecognizer alloc] initWithTarget:(id)self.delegate
action:@selector(handleLongPress:)];
[longPressGR setDelegate:(id)self.delegate];
The program runs but is unresponsive. I’m not sure if this happens because it [a] sends messages that conform to a protocol the handlers ignore OR [b] can’t find a way to send messages that conform to a protocol the handlers recognise. References I’ve looked at give no clue whether it is [a] or [b]. Moreover this document uses the term subclassing to mean something different to subclassing in my situation and the illustrated code examples are in Swift rather than Objective C.
This leads me to ask:
- can
UILongPressGestureRecognizer,
UITapGestureRecognizer
andUIPanGestureRecognizer
actually be used with my customised protocol ? - or does a customised protocol also require customised gesture
recognition methods rather than standard methods (i.e. pre-fixed
with
UI
) ? - either way, are there simple code changes that would let the delegate send gesture messages that conform to the customised protocol ? or
- is it possible I’m trying to do something that is conceptually flawed ?
I’d welcome answers to these questions or a better question if there is one.
OneOfSeveralSubviews.m
#import "OneOfSeveralSubviews.h"
@implementation OneOfSeveralSubviews
- (id)initView:(CGRect)rect
{
self = [super initWithFrame:rect];
if (self)
{
// Set view size and color
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];
// Create and configure two other gesture recognizers
self.userInteractionEnabled = YES;
}
return self;
}
@end
TouchController.h
#import <UIKit/UIKit.h>
#import "OneOfSeveralSubviews.h"
#import "TwoOfSeveralSubviews.h"
// #import "ThreeOfSeveralSubviews.h"
// #import "FourOfSeveralSubviews.h"
// etc.
@interface TouchController : UIViewController <FirstGestureRecognizerDelegate, SecondGestureRecognizerDelegate>
{
CGRect touchFrame;
CGRect screenFrame;
}
@property (strong, nonatomic) NSTimer *timer;
@end
TouchController.m
#import "TouchController.h"
@interface ViewController ()
@end
@implementation TouchController
- (void)viewDidLoad {
[super viewDidLoad];
OneOfSeveralSubviews *oneForAll=[[OneOfSeveralSubviews alloc] initView:[UIScreen mainScreen].bounds];
[self.view addSubview:oneForAll];
}
I've looked through these related posts:
- Implementing a Custom Gesture Recognizer
- UIGestureRecognizers
- Working with protocols
- Conventions
- Avoid category method name clashes
- Customizing Existing Classes
- Handling app delegates and switching between views
- differences between weak and assign property?
NOTE
I checked Scott’s duplicate question and it is definitely asking a question similar to those being asked here. But in Scott’s example it also looks as if delegation that originates inside the ViewController
is destined for a target outside the Viewcontroller
(i.e. in MakePlantTVC
). Whereas in my case, delegation that originates outside the ViewController
is destined for a target inside the ViewController.
For that reason I would never have picked Scott’s question as a duplicate even though to a more experienced person such a difference might seem insignificant.
These possible duplicates are very similar but don't solve my problem:
initWithTarget:(id)self.delegate
,self.delegate
isnil
. – Octo