UISwipeGestureRecognizer selector not called. Any idea why? - iphone

I'm using the code below to integrate right/left swipe events to a UIImageView object (called photo_view) but it did not work after tests in iphone simulator and device. The methods handleLeftSwipe and handleRightSwipe below are not even called as logging didn't print anything in the debugger logs as it should. Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
UISwipeGestureRecognizer *leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSwipe:)];
leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
leftSwipeRecognizer.numberOfTouchesRequired = 1;
[photo_view addGestureRecognizer:leftSwipeRecognizer];
leftSwipeRecognizer.delegate = self;
[leftSwipeRecognizer release];
UISwipeGestureRecognizer *rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleRightSwipe:)];
rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipeRecognizer.numberOfTouchesRequired = 1;
[photo_view addGestureRecognizer:rightSwipeRecognizer];
rightSwipeRecognizer.delegate = self;
[rightSwipeRecognizer release];
}
- (void)handleLeftSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"handleLeftSwipe called");
}
- (void)handleRightSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"handleRightSwipe called");
}
Any idea what the reason ?
Thx in advance for helping,
Stephane

UIImageView instances defaults userInteractionEnabled to NO. Try setting it to YES.

Make Sure you're also including the <UIGestureRecognizerDelegate> in your .h file.

Related

UILongPressGesture in iphone sdk

UILongPressGestureRecognizer *longPressOnUndoGesture = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPressOnUndoGesture:)];
[longPressOnUndoGesture setMinimumPressDuration:2.0];
[longPressOnUndoGesture release];
i have the above code to deasctivate the autoscroll timer in my applicationthis is the function for this.
-(void) handleLongPressOnUndoGesture:(UILongPressGestureRecognizer*)recognizer {
[autoscrollTimer invalidate];
}
but when i taptohold for 2 seconds it wont stop the timer.is there any error in my code for gesture.
Thanks in advance.
You're not using the gesture recognizer, as you release it immediately as you created it. You have to attach it to a view like this:
UILongPressGestureRecognizer *longPressOnUndoGesture = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPressOnUndoGesture:)];
[longPressOnUndoGesture setMinimumPressDuration:2.0];
// TRICK HERE
[self.view addGestureRecognizer:longPressUndoGesture];
[longPressOnUndoGesture release];
It seems to me that you are not adding the gesture recognizer to the view it should work upon:
[self.view addGestureRecognizer: longPressOnUndoGesture];
(if self is your controller).

Is it possible to attach UIGestureRecognizer to subclassed UIImageView?

Getting a crash with "unrecognized selector sent to instance" message, when attaching a UIPanGestureRecognizer to subclassed UIImageView. I need to subclass UIImageView to hold custom properties, so I just did that and added those properties. I have tested panning on UIImageView directly, and it works as expected. However, it doesn't work with subclassed UIImageView. Here's the code (self.myImageView is subclassed UIImageView and self.defaultImageView is UIImageView ):
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer * pgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveCustomImageView:)];
[self.myImageView addGestureRecognizer:pgr]; //nop, getting error during runtime on start panning
[pgr release];
...
pgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveUIImageView:)];
[self.defaultImageView addGestureRecognizer:pgr]; //yep, that works
[pgr release];
The handler methods declarations are of the same structure
-(void)moveUIImageView:(UIPanGestureRecognizer *)pan{
...
}
-(void)moveCustomImageView:(UIPanGestureRecognizer *)pan{
...
}
UIImageView by default has setUserInteractionEnabled flag set to NO & setMultipleTouchEnabled set to NO. Did you try turning these flags to YES?
You can change this like so -
[self.myImageView setMultipleTouchEnabled:YES];
[self.myImageView setUserInteractionEnabled:YES];

QLPreviewController's view

I just trying to get to QLPreviewController.view. Indeed, I want to catch a tap event on its view to show/hide toolbar etc. I am trying:
QLPreviewController* qlpc = [QLPreviewController new];
qlpc.delegate = self;
qlpc.dataSource = self;
qlpc.currentPreviewItemIndex=qlIndex;
[navigator pushViewController:qlpc animated:YES];
qlpc.title = [path lastPathComponent];
[qlpc setToolbarItems:[NSArray arrayWithObjects:self.dirBrowserButton,self.space, self.editButton, self.btnSend, nil] animated:YES];
UITapGestureRecognizer* gestTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showControls:)];
gestTap.cancelsTouchesInView=NO;
[qlpc.view addGestureRecognizer:[gestTap autorelease]];
[qlpc release];
And nothing happens
If I attach UITapRecognizer onto navigationController.view, it fires only if I touch toolbar/navbar. UISwipeGestureRecognizer works fine in that case.
I tried to attach a transparent overlay view and add gesture recognizers on it, but no luck.
Well, I saw some apps that implements such a feature so obviously it is possible, but how?
Sorry, I googled all day long and didn't find any solution. Please, help me.
With your solution, does the QLPreviewController's view still recieve touches? I've tried to do something similar (I'm stealing the view from QLPreviewController to use it) and it looks like my overlay view doesn't let anything pass trough to the view lying behind it.
I have been working on this problem today and the suggestion to override -(void)contentWasTappedInPreviewContentController:(id)item {} is close but when you do you mess with the preview controllers handling.
So I stopped overriding that method and instead created a RAC signal that fires whenever the method is called. This does not mess with the default behavior of QL. I am doing it in a subclass of the QLPreviewController but that shouldn't be necessary.
I have a property on my class:
#property RACSignal *contentTapped;
Then in my init method of my subclass of QLPreviewController:
_contentTapped = [self rac_signalForSelector:#selector(contentWasTappedInPreviewContentController:)];
Now in another class or even internally you can use the signal like this:
previewController.contentTapped subscribeNext:^(id x) {
// Put your handler here!
}];
Here is my solution (to use KVO), where I'm monitoring navigation bar status - and showing toolbar when needed (it seems that it hides toolbar by itself when tapped)
#define kNavigationBarKeyPath #"navigationBar.hidden"
static void * const NavigationBarKVOContext = (void*)&NavigationBarKVOContext;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setToolbarHidden:NO];
[self.navigationController addObserver:self forKeyPath:kNavigationBarKeyPath options:NSKeyValueObservingOptionPrior context:NavigationBarKVOContext];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController removeObserver:self forKeyPath:kNavigationBarKeyPath];
}
And
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ( context == NavigationBarKVOContext ) {
BOOL prior = [change[NSKeyValueChangeNotificationIsPriorKey] boolValue];
if ( prior && self.navigationController.toolbarHidden ) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController setToolbarHidden:NO animated:YES];
});
}
}
}
I found none of the answers here to work, but the one that did for me was to subclass QLPreviewController and override viewDidAppear as so:
- (void)viewDidAppear:(BOOL)animated
{
UITapGestureRecognizer *gestTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showControls:)];
gestTap.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:[gestTap autorelease]];
}
Ok, solution is very simple.
just added an overlay view onto keyWindow. Attached gesture recognizers onto overlay and it works.
QLPreviewController* qlpc = [QLPreviewController new];
qlpc.delegate = self;
qlpc.dataSource = self;
qlpc.currentPreviewItemIndex=qlIndex;
[navigator pushViewController:qlpc animated:YES];
qlpc.title = [path lastPathComponent];
UIView* overlay = [[[UIView alloc] initWithFrame:navigator.view.bounds] autorelease];
[[[UIApplication sharedApplication] keyWindow] addSubview:overlay];
[overlay setNeedsDisplay];
[qlpc setToolbarItems:[NSArray arrayWithObjects:self.dirBrowserButton,self.space, self.editButton, self.btnSend, nil] animated:YES];
UITapGestureRecognizer* gestTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showControls:)];
gestTap.cancelsTouchesInView=NO;
[overlay addGestureRecognizer:[gestTap autorelease]];
[qlpc release];
Subclass QLPreviewController and then override
-(void)contentWasTappedInPreviewContentController:(id)item
{}
Thats its !

Blinking UILabel Cocoa Touch

Is it possible to make a blinking UILabel in Cocoa Touch or do I need an UIview with Core Animation for that?
Take Martin's advice, and then have a look at NSTimer to handle the "blink" actions.
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
All UIViews (including UILabel) has a hidden property which you can toggle on and off to make it "blink".
For fun, I decided to write this subclassing NSOperation.
Excerpt from BlinkingLabelOperation.m
- (void)main {
SEL update = #selector(updateLabel);
[self setThreadPriority:0.0];
while (![self isCancelled]) {
if (label_ == nil)
break;
[NSThread sleepForTimeInterval:interval_];
[self performSelectorOnMainThread:update withObject:nil waitUntilDone:YES];
}
}
- (void)updateLabel {
BlinkingColors *currentColors = nil;
if (mode_)
currentColors = blinkColors_;
else
currentColors = normalColors_;
[label_ setTextColor:currentColors.textColor];
[label_ setBackgroundColor:currentColors.backgroundColor];
mode_ = !mode_;
}
Sample view controller code:
- (void)viewDidLoad
{
[super viewDidLoad];
BlinkingColors *blinkColors = [[BlinkingColors alloc] initWithBackgroundColor:[UIColor whiteColor]
textColor:[UIColor redColor]];
BlinkingLabelOperation *blinkingOp = [[BlinkingLabelOperation alloc] initWithLabel:clickLabel freq:1.0 blinkColors:blinkColors];
// put the operation on a background thread
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:blinkingOp];
[blinkColors release];
}
For a complete listing, you will find it here. Please leave comments and let me know what are your thoughts.

Using UIImagePickerController in the game

I want to make a game, where the user can touch a picture of a TV and then choose a picture from their photo library.
I had success working with UITextFields, adding them to my EAGLView as subviews But I haven't been able to do the same thing with an UIImagePickerController , which seems the only way to do what I want to do.
Any help is appreciated !
UPDATE
With the suggestion of zpasternack I managed to make the menu appear by adding the UIImagePickerControllerDelegate, UINavigationControllerDelegate and using this method:
- (void) chooseImageFromLibrary {
if( ![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] ) return;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.allowsEditing = YES;
[self addSubview:imagePickerController.view];
[imagePickerController viewWillAppear:YES];
[imagePickerController viewDidAppear:YES];
}
I call the chooseImageFromLibrary method at the start. It shows the interface, but as soon as i hit cancel or choose the app stops.
Can anyone suggest me:
1) How to make the cancel and choose buttons work.
2) How to call the UIImagePickerController whenever I want ( by calling chooseImageFromLibrary again ??).
3) When the user hits choose..Where do i find the UIImage the user just picked to ?, how do i pick it ?
Thanks.
I've never used one over an EAGLView, but UIImagePickerControllers are typically invoked with presentModalViewController, like:
- (void) chooseImageFromLibrary {
if( ![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] ) return;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.allowsEditing = YES;
[self presentModalViewController:imagePickerController animated:YES];
}
Nervermind, problem solved. i just needed to overwrite some functions to make use of the UIImagePickerController.