Why doesn't Xcode recognize -ignoreTouch:forEvent: in UITapGestureRecognizer subclass? - iphone

According to documentation there is a method -ignoreTouch:forEvent:. I need to mimic a -pointInside:withEvent: functionality to make it handle taps only specific shape.
But when I try call this method Xcode doesn't know it. No autocompletion and it gives error for undeclared method. But documentation clearly says we can call ignoreTouch:forEvent: on UITapGestureRecognizer to ignore a touch.
Edit: Documentation says there is a class extension for it but I cant import this either. Not found: #import "UIGestureRecognizerSubclass.h"

It's part of UIKit so import it like this:
#import <UIKit/UIGestureRecognizerSubclass.h>

It seems when I do this it works:
#import <UIKit/UIGestureRecognizerSubclass.h>
#implementation OFShapeTapGestureRecognizer
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//[self ignoreTouch:[touches anyObject] forEvent:event];
// ... here, fancy logic.
if (ignore) {
self.state = UIGestureRecognizerStateCancelled;
}
}

Related

No visible #interface for 'NSObject<PageControlDelegate>' declares the selector 'pageControlPageDidChange:'

I've got this code from this post and everything is ok except one thing, I have this error that I dont know how to fix. this is the code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];
CGRect currentBounds = self.bounds;
CGFloat x = touchPoint.x - CGRectGetMidX(currentBounds);
if(x<0 && self.currentPage>=0){
self.currentPage--;
[self.delegate pageControlPageDidChange:self];
}
else if(x>0 && self.currentPage<self.numberOfPages-1){
self.currentPage++;
[self.delegate pageControlPageDidChange:self];
}
}
the error is that:
No visible #interface for 'NSObject<PageControlDelegate>' declares the selector 'pageControlPageDidChange:'.
I've tried to run this code with ARC, I removed the dealloc method, changed assign to weak in here:
#property (nonatomic, weak) NSObject<PageControlDelegate> *delegate;
as someone wrote in the answers, but still it isn't working.
Please help me.
If in your header you just have:
#protocol PageControlDelegate;
You missed the actual definition of what the protocol is. At the bottom of that first code block in your linked post there is this code that contains the declaration of the missing protocol function:
#protocol PageControlDelegate<NSObject>
#optional
- (void)pageControlPageDidChange:(PageControl *)pageControl;
#end
You need to import the .h file that declares the PageControlDelegate protocol.

How do I apply a UILongPressGestureRecognizer to a shape in C4?

I am working in C4 and want to be able to press down on a shape and drag it at a slow speed upward.
I have been working with the "Getting the UITouch objects for a UIGestureRecognizer" tutorial and other TouchesMoved and TouchesBegan Objective-C tutorials but the gesture is not applying to the shape. The project builds but the shape still does not move when you press and drag it. Is there a particular way C4 applies gestures to shapes?
This is my code:
DragGestureRecognizer.h
#import <UIKit/UIKit.h>
#interface DragGestureRecognizer : UILongPressGestureRecognizer {
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
#end
#protocol DragGestureRecognizerDelegate <UIGestureRecognizerDelegate>
- (void) gestureRecognizer:(UIGestureRecognizer *)gr movedWithTouches:(NSSet*)touches andEvent:(UIEvent *)event;
#end
C4WorkSpace.m:
#import "C4WorkSpace.h"
#import "DragGestureRecognizer.h"
#implementation DragGestureRecognizer
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if ([self.delegate respondsToSelector:#selector(gestureRecognizer:movedWithTouches:andEvent:)]) {
[(id)self.delegate gestureRecognizer:self movedWithTouches:touches andEvent:event];
}
}
#end
#implementation C4WorkSpace {
C4Shape *circle;
}
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(#"Long Press");
}
}
-(void)setup {
circle = [C4Shape ellipse:CGRectMake(5,412,75,75)];
[self.canvas addShape:circle];
}
#end
C4 has a method that simplifies the process of adding gestures to any visible object (e.g. C4Shape, C4Movie, C4Label...).
NOTE: you will need to create a subclass of C4Shape in which you can create some custom methods.
For instance, the following will add a tap gesture to an C4Shape:
C4Shape *s = [C4Shape rect:CGRectMake(..)];
[s addGesture:TAP name:#"singleTapGesture" action:#"tap"];
The addGesture:name:action: method is listed in the C4Control documentation, and is defined like:
Adds a gesture to an object.
- (void)addGesture:(C4GestureType)type name:(NSString *)gestureName action:(NSString *)methodName
The (C4GestureType)type can be any one of:
TAP
SWIPERIGHT
SWIPELEFT
SWIPEUP
SWIPEDOWN
PAN
LONGPRESS
The following gestures are available, but haven't yet been tested:
PINCH
ROTATION
The (NSString *)gestureName allows you to specify a unique name for the gesture.
The (NSString *)methodName allows you to specify the method that the gesture will trigger.
So... getting back to the example above:
[s addGesture:TAP name:#"singleTapGesture" action:#"tap"];
...will add to the s object a TAP gesture called singleTapGesture which, when triggered, will run a -(void)tap; method (which needs to have already defined in your class).
You can apply the technique I described above, but instead use:
[s addGesture:PAN name:#"panGesture" action:#"move:];
you will also have to define a
-(void)move:(id)sender;
method in your shape's class.

Subclassing MKOVerlay View- canDrawMapRect not called

I am attempting to subclass MKOverlayView to create a custom overlay. I understand that in order to do this, one must override the following two methods
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context;
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale;
My question arrises from the latter method. For some reason, when I override it in my MKOverlayView subclass, it does not get called. According to documentation, it should be called before tiles are rendered and if it returns YES, then drawMapRect is called. I was hoping that someone could look at the following code and see if they can figure out why this method is not being called. Is it meant to be enabled/called manually somewhere?
Interestingly enough, drawMapRect does get called, it's only canDrawMapRect that does not. Am I misinterpreting the functionality of canDrawMapRect or is something wrong in my code?
HeatMapOverlay.h
#import <MapKit/MapKit.h>
#import <Foundation/Foundation.h>
#interface HeatMapOverlayView : MKOverlayView{
...variables...
}
#end
HeatMapOverlay.m
#import "HeatMapOverlayView.h"
#import <CoreGraphics/CoreGraphics.h>
#import <QuartzCore/QuartzCore.h>
#implementation HeatMapOverlayView
#synthesize points, heat, QualityIndex;
- (id)initWithOverlay:(id<MKOverlay>)overlay {
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale{
...complete check...
return NO;
}
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext (CGContextRef)context{
...draw overlay...
}
Thank you!
Try changing this line:
self = [super init];
to this to use the proper initializer for an MKOverlayView:
self = [super initWithOverlay:overlay];

Override method syntax ios

I'm trying to override a method in my cellForRowAtIndexPath method like this
cell.customSwitch {
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesEnded:touches withEvent:event];
NSLog(#"customSwitch touchesended");
}
};
however this isn't working (I'm normally a Java guy :P). Any help would be much appreciated!
There are a lot of similarities between Objective-C and Java, but that's not one of 'em. ;-)
If you want to create a cell with a customized -touchesEnded:withEvent: method, you'll need to declare and define that class separately. Something like:
#interface MyCell : UITableViewCell
{
//...
}
#end
#implementation MyCell
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesEnded:touches withEvent:event];
NSLog(#"customSwitch touchesended");
}
#end
Once you've done that, you can use MyCell in your -cellForRowAtIndexPath:.

Subclassing UIScrollView/UIScrollViewDelegate

I'm trying to create my own custom UIScrollView, so that I can pass touch events from it to a delegate object which has logic to draw to an imageview inside the scrollview.
If I remove the delegate variable and property from the class interface it works fine as a normal scroll view. When I make it my custom protocol delegate it builds but doesn't pass on messages..
Any help appreciated
#class DrawableScrollView;
#protocol DrawableScrollViewDelegate <UIScrollViewDelegate>
- (void)touchesBegan:(DrawableScrollView *)drawableScrollView touches:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(DrawableScrollView *)drawableScrollView touches:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(DrawableScrollView *)drawableScrollView touches:(NSSet *)touches withEvent:(UIEvent *)event;
#end
#interface DrawableScrollView : UIScrollView {
id<DrawableScrollViewDelegate> delegate;
}
#property (nonatomic, assign) IBOutlet id<DrawableScrollViewDelegate> delegate;
#end
Chances are that the UIScrollView methods that pass on the delegate messages use the (private) ivar to access the delegate, rather than using the property accessor each time. So when you override those with your own delegate property, the underlying scrollview delegate never gets set.
One way around this would be to use the UIScrollView's implementation of delegate and setDelegate: to store your delegate, instead of or in addition to using your own ivar. Another would be to rename your property to avoid the conflict. A third would be to make the view inside the scrollview respond to the touches, rather than messing with the scrollview itself.
Why not just let the imageView handle the touches?