iOS5 GestureRecognizer fires only on the second tap - objective-c

Would anyone have an idea why Tap gesture recognizer is called only after second tap in ios5, although in ios6 it works fine after one tap.
The code works in ios6, I tried this code also in separate project and works as well for ios5, I think it's linked to the project settings, but I cannot find out which.
My Code is:
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = questTitle;
//add coretextview
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
coreTextView = [[FTCoreTextView alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
coreTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// set text
[coreTextView setText:[self textForView]];
// set styles
[coreTextView addStyles:[self coreTextStyle]];
// set delegate
[coreTextView setDelegate:self];
[coreTextView fitToSuggestedHeight];
scrollView.scrollEnabled = TRUE;
[scrollView addSubview:coreTextView];
[scrollView setContentSize:CGSizeMake(CGRectGetWidth(scrollView.bounds), CGRectGetHeight(coreTextView.frame) + 40)];
[self.view addSubview:scrollView];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
tapGesture.delegate = (id <UIGestureRecognizerDelegate>)self;
[coreTextView addGestureRecognizer:tapGesture];
tapGesture.numberOfTapsRequired = 1; // How many taps
tapGesture.numberOfTouchesRequired = 1;
coreTextView.userInteractionEnabled = YES;
tapGesture.cancelsTouchesInView = NO;
scrollView.userInteractionEnabled = YES;
scrollView.exclusiveTouch = NO;
scrollView.delegate = self;
[tapGesture release];
}
- (void)pan:(UITapGestureRecognizer*)sender {
NSLog(#"Pan tap");
}
- (BOOL)gestureRecognizerShouldBegin:(UITapGestureRecognizer *)gestureRecognizer{
NSLog(#"tap");
return YES;
}
- (BOOL)gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UITapGestureRecognizer *)otherGestureRecognizer{
NSLog(#"tap");
return YES;
}
- (BOOL)gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
NSLog(#"tap");
return YES;
}

Related

add UINavigationController onto a UIScrollView

I'm putting a NavigationController as a child VC on a ScrollView. Here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.automaticallyAdjustsScrollViewInsets = YES;
_scrollView = [UIScrollView newAutoLayoutView];
_scrollView.alwaysBounceVertical = YES;
_scrollView.delaysContentTouches = NO;
[self.view addSubview:_scrollView];
[_scrollView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
_contentView = [UIView newAutoLayoutView];
UIView *yellowView = [UIView newAutoLayoutView];
yellowView.backgroundColor = [UIColor yellowColor];
[_contentView addSubview:yellowView];
[yellowView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[yellowView autoSetDimensionsToSize:CGSizeMake(kScreenWidth, kScreenHeight)];
[_scrollView addSubview:_contentView];
_settingsNavigationController = [UINavigationController new];
[self addChildViewController:_settingsNavigationController];
[_contentView addSubview:_settingsNavigationController.view];
[_settingsNavigationController didMoveToParentViewController:self];
[_settingsNavigationController.view autoSetDimensionsToSize:CGSizeMake(kScreenWidth, kScreenHeight)];
[_settingsNavigationController.view autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:yellowView];
[_settingsNavigationController.view layoutSubviews];
[_contentView autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:_settingsNavigationController.view];
[_contentView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[_contentView autoPinEdge:ALEdgeLeading toEdge:ALEdgeLeading ofView:self.view];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
PCConfigViewController *configViewController = [PCConfigController new];
configViewController.morning = YES;
configClockViewController.delegate = self;
[_settingsNavigationController setViewControllers:[NSArray arrayWithObject:configViewController] animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
I can scroll to the NavigationController and see its root view controller but it doesn't respond to touches, even though the NavigationController was added as a child view controller. Any ideas why, or how to make it responsive to touch?

How to fade BOTH status bar and navigation bar LIKE Photos.app, on iOS 7

Basically, it's a very simple demand, but I've tried several methods and none of them works as expected. The closest functioning snippet is:
#import "ViewController.h"
#implementation ViewController
- (void)dealloc
{
[scrollView release];
scrollView = nil;
[super dealloc];
}
- (id)init
{
if (self = [super init])
{
self.title = #"Pictures";
scrollView = [[UIScrollView alloc] init];
scrollView.delegate = self;
scrollView.frame = CGRectMake(0.0f, 0.0f, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
scrollView.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width * 10, scrollView.bounds.size.height);
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.pagingEnabled = YES;
scrollView.userInteractionEnabled = YES;
scrollView.backgroundColor = [UIColor blackColor];
self.wantsFullScreenLayout = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
isHidden = NO;
}
return self;
}
- (void)viewDidLoad
{
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[scrollView addGestureRecognizer:tapGesture];
[tapGesture setNumberOfTapsRequired:1];
[tapGesture release];
for (int i = 0; i < 10; i++)
{
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:#"/path/to/%d.png", i + 1]];
UIImageView *imageView= [[UIImageView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width * i, 0.0f, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = image;
[scrollView addSubview:imageView];
[image release];
[imageView release];
}
[self.view addSubview:scrollView];
}
- (void)tap:(UITapGestureRecognizer *)gesture
{
[UINavigationBar setAnimationDuration:1.0];
[UINavigationBar beginAnimations:#"HideTopBars" context:nil];
isHidden = !isHidden;
// [self setNeedsStatusBarAppearanceUpdate];
self.navigationController.navigationBar.alpha = isHidden ? 0.0f : 1.0f;
[UINavigationBar commitAnimations];
}
- (void)scrollViewDidScroll:(UIScrollView *)view
{
// further operation
}
- (BOOL)prefersStatusBarHidden
{
return isHidden;
}
#end
Without "[self setNeedsStatusBarAppearanceUpdate]", navigation bar does fade as expected, but texts on status bar remain visible, which I guess is because status bar takes navigation bar as it's background image and status bar itself doesn't fade; With "[self setNeedsStatusBarAppearanceUpdate]", the texts also fade, but navigation bar's animation becomes sliding in/out from the top of the screen along with fade effect. I've also tried to move "[self setNeedsStatusBarAppearanceUpdate]" into prefersStatusBarHidden, but that just made navigation bar visible forever. I believe this is not an odd demand, so I bet there're better and simpler solutions. Any idea?

UIImageView subclass doesn't work simultaneously gesture

I'm developing a iOs 6 app for iPad. I've developed a UIImageView subclass adding gesture recognizing (zoom, pinch and pan), but I've a problem: it doesn't admit simultaneously gestures. I first code it as a normal UIImageView, and it worked great, but now with the subclass it doesn't. My code:
image.m (UIImageView subclass)
- (id)initWithImage:(UIImage *)image {
self = [super initWithImage:image];
if (self) {
[self setMultipleTouchEnabled:YES];
[self setUserInteractionEnabled:YES];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panDetected:)];
[super addGestureRecognizer:panRecognizer];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchDetected:)];
[super addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationDetected:)];
[super addGestureRecognizer:rotationRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
tapRecognizer.numberOfTapsRequired = 2;
[super addGestureRecognizer:tapRecognizer];
NSLog(#"lkjlkj");
}
return self;}
- (void)panDetected:(UIPanGestureRecognizer *)panRecognizer {
CGPoint translation = [panRecognizer translationInView:self.superview];
CGPoint imageViewPosition = self.center;
imageViewPosition.x += translation.x;
imageViewPosition.y += translation.y;
self.center = imageViewPosition;
[panRecognizer setTranslation:CGPointZero inView: self.superview];}
- (void)pinchDetected:(UIPinchGestureRecognizer *)pinchRecognizer{
CGFloat scale = pinchRecognizer.scale;
self.transform = CGAffineTransformScale(self.transform, scale, scale);
pinchRecognizer.scale = 1.0;}
- (void)rotationDetected:(UIRotationGestureRecognizer *)rotationRecognizer{
CGFloat angle = rotationRecognizer.rotation;
self.transform = CGAffineTransformRotate(self.transform, angle);
rotationRecognizer.rotation = 0.0;}
- (void)tapDetected:(UITapGestureRecognizer *)tapRecognizer{
[UIView animateWithDuration:0.25 animations:^{
self.center = CGPointMake(CGRectGetMidX(self.superview.bounds), CGRectGetMidY(self.superview.bounds));
self.transform = CGAffineTransformIdentity;
}];}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;}
viewcontroller.m (where I create a imageview from image which doesn't respond to multiple gestures simultaneously)
image *img = [[image alloc] initWithImage:imatgetemporal];
img.center = CGPointMake(525/2, 651/2);
[[self.view viewWithTag:2] addSubview:img];
Thanks for all!!
I guess you can solve it by adding the same delegate to the UIPanGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer and to the UITapGestureRecognizer just after declaring them. The code would be like this:
tapRecognizer.delegate = self;
pinchRecognizer.delegate = self;
rotationRecognizer.delegate = self;
tapRecognizer.delegate = self;
Hope it helps.

Hijack "swipe to next page" in UIScrollView

i'd like to prevent scrolling on the 3rd page of my UIScrollview and "hijack the swipe" gesture to trigger sth. else. Afer this action I'd like to reactive scrolling.
This does not work.
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
if(scrollView.contentOffset.x == self.view.frame.size.width * 2 ) {
// disable scrolling
scrollView.scrollEnabled = NO;
}
}
// hijack the next scrolling event
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
This delegate is not called when scrollEnabled = NO
Thanks for helping
EDIT EventHandler ist not called ;-(
- (void)viewDidLoad
{
[super viewDidLoad];
// Default background color
self.view.backgroundColor = [UIColor redColor];
// Create scroll view
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
recognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[scrollView addGestureRecognizer:recognizer];
[recognizer release];
[scrollView delaysContentTouches];
// Create subviews (pages)
NSInteger numberOfViews = 4;
for (int i = 0; i < numberOfViews; i++) {
// x pos
CGFloat yOrigin = i * self.view.frame.size.width;
// Create subview and add to scrollView
UIView *pageView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
pageView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scrollView addSubview:pageView];
[pageView release];
}
// Set contentsize
scrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
// Add scrollView to view and release
[self.view addSubview:scrollView];
[scrollView release];
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"swipe!!!!");
scrollView.scrollEnabled = YES;
}
If you disable the scroll view:
scrollView.scrollEnabled = NO;
it is unavoidable that the delegate method is not called, so you need an alternative way to handle the swipe while in hijack mode. One thing you could try is using an UISwipeGestureRecognizer: instead of simply disabling scrolling, you could associate a UISwipeGestureRecognizer to you view and handle the swipe from the handler method:
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
recognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:recognizer];
and in handleSwipeFrom you would reenable scrolling:
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
// do your hijack here
scrollView.scrollEnabled = YES;
}

No scrolling or user interaction in new NSWindow with NSScrollView

I am building an application (without interface builder!) which 'lives' in the NSStatusBar; when you click on an icon in the StatusBar a NSWindow with a NSScrollView appears. The window appears but it seems that something is preventing user interaction with the ScrollView
To find out where the problem comes from I also added my view to the main windows contentView in the AppDelegate, strange thing is that the scrollview is interactive in the MainWindow... Anyone knows why it doesn't work in my new Window?
This is the code I use to create the new TTDropDownWindow:
- (void)openWindow {
// Dropdown
if (self.dropDownWindow == nil) {
self.dropDownWindow = [[TTDropDownWindow alloc] init];
self.dropDownWindow.releasedWhenClosed = NO;
self.dropDownWindow.contentView = self.view;
self.dropDownWindow.backgroundColor = [NSColor clearColor];
self.dropDownWindow.delegate = self;
self.dropDownWindow.alphaValue = 1;
self.dropDownWindow.hasShadow = NO;
self.dropDownWindow.opaque = NO;
}
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSRect statusBarContentRect = self.statusBarItemView.window.frame;
NSPoint statusBarOriginPoint = NSMakePoint(NSMidX(statusBarContentRect), NSMinY(statusBarContentRect));
NSRect screenFrame = self.dropDownWindow.screen.frame;
NSRect dropDownContentRect = NSZeroRect;
dropDownContentRect.size.width = DROP_DOWN_WIDTH;
dropDownContentRect.size.height = DROP_DOWN_HEIGHT;
dropDownContentRect.origin.x = statusBarOriginPoint.x - DROP_DOWN_WIDTH / 2;
dropDownContentRect.origin.y = screenFrame.size.height - DROP_DOWN_HEIGHT - NSStatusBar.systemStatusBar.thickness;
[self.dropDownWindow setFrame:dropDownContentRect display:YES];
[self.dropDownWindow makeKeyAndOrderFront:nil];
}
This is the implementation of TTDropDownWindow:
#import "TTDropDownWindow.h"
#import "WFConstants.h"
#implementation TTDropDownWindow
- (id) init
{
self = [super initWithContentRect:NSMakeRect(0, 0, DROP_DOWN_WIDTH, DROP_DOWN_HEIGHT) styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:NO];
return self;
}
- (BOOL)canBecomeMainWindow {
return YES;
}
- (BOOL)canBecomeKeyWindow {
return YES;
}
#end
And this is the code that creates the View and the ScrollView
#import "TTStatusBarDropDownView.h"
#import "TTTestView.h"
#implementation TTStatusBarDropDownView
#synthesize dropDownTableViewData = dropDownTableViewData_;
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
NSImageView *imageView = [[NSImageView alloc] initWithFrame:frameRect];
imageView.image = [NSImage imageNamed:#"background-dropdown"];
[self addSubview:imageView];
// first create a view to put in a ScrollView
NSView *scrollViewHolder = [[TTTestView alloc] initWithFrame:NSMakeRect(19, 98, 414, 543) andColor:[NSColor yellowColor]];
[self addSubview:scrollViewHolder];
// create the scrollView
NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 414, 543)];
scrollView.hasVerticalRuler = YES;
scrollView.hasVerticalScroller = YES;
[scrollViewHolder addSubview:scrollView];
// TTTestView is just a NSView with a background drawing
TTTestView *theViewThatScrolls = [[TTTestView alloc] initWithFrame:NSMakeRect(0, 0, 200, 10000) andColor:[NSColor blueColor]];
[theViewThatScrolls addSubview:[[TTTestView alloc] initWithFrame:NSMakeRect(10, 10, 100, 8000) andColor:[NSColor grayColor]]];
[scrollView setDocumentView:theViewThatScrolls];
}
return self;
}
#end
You might change NSBackingStoreRetained to NSBackingStoreBuffered as stated over here:
NSScrollView in a NSWindow