Choose different UIPanGestureRecognizer touches - nsuserdefaults

Ok so I have a app with a left menu and a right view controller which are controlled by the UIPanGestureRecognizer. So when a user swipes the bezel (20px) of the edge of the screen it navigates.
In a settings view controller I have UISwitches which control various other things, but one of them I want to control how many touches the UIPanGestureRecognizer will take.
The switch is set up properly and sends the user defaults to the other view controller, but on the receiving end of it, it won't read what the user has selected.
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureCallback:)];
//Switch for SwipeNav
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:#"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[pan setMinimumNumberOfTouches:2];
[pan setMaximumNumberOfTouches:2];
}else{
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
}
[pan setDelegate:self];
[self.view addGestureRecognizer:pan];
How can I make it so when the switch is on, it uses 2 touches to navigate, and off it acts like normal?
Any assistance is always appreciated. Thank you.
UPDATED with settings sync code.
if (swipe){
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:self.swipe.on forKey:#"SwipeNav"];
[userDefaults synchronize];
if ([swipe isOn]) {
[swipe setOn:YES animated:YES];
[self.tableView reloadData];
[[UIApplication sharedApplication] reloadInputViews];
} else {
[swipe setOn:NO animated:YES];
[self.tableView reloadData];
[[UIApplication sharedApplication] reloadInputViews];
}
}

I created a new project and tried to reproduce the problem that you are seeing and everything seems to work as expected. When switch is on the you need two buttons to pan and when switch is off you only need one. Let me know if that points you in the right direction. Your code seems to be correct.
I copy pasted the handlePan function from How to use UIPanGestureRecognizer to move object? iPhone/iPad
Created everything programmatically and copy pasted your code to save the state of the switch. Here is the code from two UIViewControllers
//
// ViewController.m
// StackOverflowSwitch
//
//
//
//
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic,strong) UIButton *myButton;
#property (nonatomic,strong) UISwitch *switchOn;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.myButton = [[UIButton alloc]initWithFrame:CGRectMake(10, 100, 150, 150)];
self.switchOn = [[UISwitch alloc]initWithFrame:CGRectMake(10, 300, 100, 100)];
self.myButton.backgroundColor =[UIColor grayColor];
[self.myButton setTitle:#"Click Me" forState:UIControlStateNormal];
[self.myButton addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.switchOn];
[self.view addSubview:self.myButton];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)click:(UIButton *)sender
{
[self performSegueWithIdentifier:#"NextViewController" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if(self.switchOn.on){
NSLog(#"switch is on");
}else{
NSLog(#"switch is off");
}
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:self.switchOn.on forKey:#"SwipeNav"];
[userDefaults synchronize];
}
#end
//////
#import "SecondViewController.h"
#interface SecondViewController() <UIGestureRecognizerDelegate>
#property (strong,nonatomic) UIView *myView;
#end
#implementation SecondViewController
-(void)viewDidLoad
{
[super viewDidLoad];
self.myView = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 200, 200)];
self.myView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.myView];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:#"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[pan setMinimumNumberOfTouches:2];
[pan setMaximumNumberOfTouches:2];
}else{
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
}
[pan setDelegate:self];
[self.view addGestureRecognizer:pan];
[self.myView addGestureRecognizer:pan];
}
-(void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(#"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
#end
///// Update
I am not exactly sure how [[UIApplication sharedApplication] reloadInputViews]; calls the function to update the UIPanGestureRecongizer in your code but i tried to recreate your functionality as close as possible by having the setupView method called every time i click the UISwitch
I created a custom view with UIPanGestureReconginzer in there and a method that I call from the UIViewController to update setNumberOfTouches. The view works as expected. The key here is not to initialize a new UIPanGuestureRecongizer but update the existing one. I assume in your app UIViewController or UIView which has the UIPanGuestureRecongizer is not being fully reloaded.
I created a property UIPanGuestureRecongizer which gets initialized the first time it's being accessed and then gets updated when switch is being pressed. Here is the custom UIView code. Let me know if you have any questions regarding the code.
#import "MyTestView.h"
#interface MyTestView() <UIGestureRecognizerDelegate>
#property(nonatomic,strong) UIPanGestureRecognizer *panGesture;
#end
#implementation MyTestView
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self setupView];
}
return self;
}
-(UIPanGestureRecognizer *)panGesture
{
//lazy instantiation
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
}
return _panGesture;
}
-(void)setupView
{
//this gets called everytime the UISwitch is being pressed.
NSLog(#"Setup views");
self.backgroundColor = [UIColor redColor];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:#"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[self.panGesture setMinimumNumberOfTouches:2];
[self.panGesture setMaximumNumberOfTouches:2];
}else{
[self.panGesture setMinimumNumberOfTouches:1];
[self.panGesture setMaximumNumberOfTouches:1];
}
[self.panGesture setDelegate:self];
[self addGestureRecognizer:self.panGesture];
}
-(void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(#"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
#end

Alright, so after much testing/code flipping, I think I have found my solution.
So a little more backstory, I use MMDrawerController, so the method above about placing [self setupView]; in (instancetype)initWithCoder didn't do anything. The setupView or in my case is called "setupGestureRecognizers" is loaded in the viewDidLoad. Anywhere else it wouldn't load the gesture's at all.
With my current switch code and gesture loading I have this:
-(UIPanGestureRecognizer *)panGestureNav {
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureCallback:)];
}
return _panGesture;
}
-(void)setupGestureRecognizers{
switchOn = [[NSUserDefaults standardUserDefaults] boolForKey:#"SwipeNav"];
if (switchOn == YES) {
// 2 Finger SwipeNav
[self.panGestureNav setMinimumNumberOfTouches:2];
[self.panGestureNav setMaximumNumberOfTouches:2];
NSLog(#"2 Finger Nav");
}else {
[self.panGestureNav setMinimumNumberOfTouches:1];
[self.panGestureNav setMaximumNumberOfTouches:1];
NSLog(#"Normal Nav");
}
[self.panGestureNav setDelegate:self];
[self.view addGestureRecognizer:self.panGestureNav];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureCallback:)];
[tap setDelegate:self];
[self.view addGestureRecognizer:tap];
}
Which would normally work, but this library does things differently, so I have to look into their gesture calling and what I ended up doing was calling it here:
-(MMOpenDrawerGestureMode)possibleOpenGestureModesForGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer withTouch:(UITouch*)touch{
CGPoint point = [touch locationInView:self.childControllerContainerView];
MMOpenDrawerGestureMode possibleOpenGestureModes = MMOpenDrawerGestureModeNone;
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]){
[self setupGestureRecognizers]; <------------
So now it loads and functions as I want.
Thank you Yan so all of your assistance. Hope this helps somebody.

Related

Multiple gestureRecognizers on views- one shouldn't pass touch

On parentClass(inheriting from UIView) i have:
[self addGestureRecognizer:_tapGesture]; // _tapGesture is UITapGestureRecognizer, with delegate on parentClass
On someClass:
[_myImageView addGestureRecognizer:_imageViewGestureRecognizer]; // _imageViewGestureRecognizer is UITapGestureRecognizer, with delegate on someClass
The problem is that when i tap on myImageView both gesture recognizers are firing. I want only _imageViewGestureRecognizer to work.
I've tried:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch {
UIView *gestureView = recognizer.view;
CGPoint point = [touch locationInView:gestureView];
UIView *touchedView = [gestureView hitTest:point withEvent:nil];
if ([touchedView isEqual:_imageViewGestureRecognizer]) {
return NO;
}
return YES;
}
But it ofc doesn't take upon consideration gesture recognizer from super class.
I did this little test and it worked perfectly...
#implementation View
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped1)];
[self addGestureRecognizer:tap];
UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
img.userInteractionEnabled = YES;
img.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:img];
UITapGestureRecognizer* tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped2)];
[img addGestureRecognizer:tap2];
return self;
}
-(void)tapped1 {
NSLog(#"Tapped 1");
}
-(void)tapped2 {
NSLog(#"Tapped 2");
}
#end
What you wanted was iOS's default behaviour. Once a subview has taken care of a touch, its superview won't receive the touch anymore. Did you set userInteractionEnabled on the imageView?

I currently have a accelerometer action that displays a image but won't clear/reset

For a exercise I created a project to experiment with the accelerometer functions of the iPhone. Right now when I run the app on my device it begins with a blank screen, shake the phone and a image is displayed.
I have to force close the app to clear the image. I was hoping someone could provide a solution that would make the image reset so I could repeat the process as many times as I wanted. (shake phone, display image, clear image) I'm thinking it needs a timer or something, not sure. Here is the source code. Thanks for taking the time to read and help.
// ViewController.m
// AccelTest
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
-(void)viewWillAppear:(BOOL)animated{
[self startAccel];
[self view];
}
-(void)viewWillDisappear:(BOOL)animated{
[self stopAccel];
[self view];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return NO;
}
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
double const kThreshold = 2.0;
// double const kThreshold = 2.0;
if ( fabsf(acceleration.x) > kThreshold
|| fabsf(acceleration.y) > kThreshold
|| fabsf(acceleration.z) > kThreshold){
[self.view addSubview:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Icon.png"]]];
}
}
-(void)startAccel{
UIAccelerometer * accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = .25;
}
-(void)stopAccel{
UIAccelerometer * accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = nil;
}
#end
Here is how I would do it (without ARC) to tap the image to make it disappear.
Remove your line:
[self.view addSubview:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Icon.png"]]];
And add these lines instead:
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Icon.png"]];
myImageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(rm:)];
[myImageView addGestureRecognizer:tapgr];
[tapgr release]; tapgr = nil;
[self.view addSubview:myImageView];
[myImageView release]; myImageView = nil;
Then add a method to the View Controller to remove the UIImageView when it is tapped.
-(void)rm:(UITapGestureRecognizer *)tapgr {
[tapgr.view removeFromSuperview];
}
When that Image is tapped once, the rm: method will be called which will remove the Image from self.view
Store a pointer to that image view somewhere and remove it from it's superview when you want to. Either with a timer, or user action, or something like that.

tableView:didSelectRowAtIndexPath not firing after swipe gesture is called

This is a localized issue. I'm going to post a lot of code, and provide a lot of explanation. Hopefully... someone can help me with this.
In my application I have a "Facebook-style" menu. The iOS Facebook app, to be more specific. You can access this menu in two different ways. You may either touch the menu button, or swipe to open the menu. When one opens and closes the menu using the button, the tableView:didSelectRowAtIndexPath method fires perfectly upon touching the cell. When one opens and closes the menu using the swipe method... it does not. You have to touch the table cell twice for the method to fire. The code for these methods are exactly the same in several classes, however, this is the only one I have an issue with. Take a look; see if I'm dropping the ball somewhere:
#import "BrowseViewController.h"
#implementation BrowseViewController
#synthesize browseView, table, countriesArray, btnSideHome, btnSideBrowse, btnSideFave, btnSideNew, btnSideCall, btnSideBeset, btnSideEmail, btnSideCancelled, menuOpen, navBarTitle, mainSearchBar, tap;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fontWithName:#"STHeitiSC-Medium" size:20.0];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.text = #"Countries";
self.navBarTitle.titleView = label;
[label sizeToFit];
CheckNetworkStatus *networkCheck = [[CheckNetworkStatus alloc] init];
BOOL internetActive = [networkCheck checkNetwork];
if (internetActive) {
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
tap.delegate = self;
tap.cancelsTouchesInView = NO;
UISwipeGestureRecognizer *oneFingerSwipeLeft =
[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft:)];
[oneFingerSwipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[[self view] addGestureRecognizer:oneFingerSwipeLeft];
UISwipeGestureRecognizer *oneFingerSwipeRight =
[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight:)];
[oneFingerSwipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
[[self view] addGestureRecognizer:oneFingerSwipeRight];
menuOpen = NO;
table.userInteractionEnabled = YES;
NSArray *countries = [[NSArray alloc] initWithObjects:#"United States", #"Canada", #"Mexico", nil];
self.countriesArray = countries;
} else {
//No interwebz, notify user and send them to the home page
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Connection Error" message:#"Failed to connect to the server. Please verify that you have an active internet connection and try again. If the problem persists, please call us at **********" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[message show];
PassportAmericaViewController *homeView = [[PassportAmericaViewController alloc]
initWithNibName:#"PassportAmericaViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:homeView animated:YES];
}
[super viewDidLoad];
}
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection: (NSInteger)section
{
return [countriesArray count];
NSLog(#"Number of objecits in countriesArray: %i", [countriesArray count]);
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont fontWithName:#"STHeitiSC-Medium" size:20.0];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [countriesArray objectAtIndex:row];
return cell;
}
- (void)tableView:(UITableView *)table
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *countrySelected = [countriesArray objectAtIndex:indexPath.row];
Campground *_Campground = [[Campground alloc] init];
_Campground.country = countrySelected;
StateViewController *stateView = [[StateViewController alloc]
initWithNibName:#"StateView" bundle:[NSBundle mainBundle]];
stateView._Campground = _Campground;
[self.navigationController pushViewController:stateView animated:YES];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(void) dismissKeyboard {
[mainSearchBar resignFirstResponder];
}
-(IBAction)goBack:(id)sender{
[self.navigationController popViewControllerAnimated:YES];
}
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if ([animationID isEqualToString:#"slideMenu"]){
UIView *sq = (__bridge UIView *) context;
[sq removeFromSuperview];
}
}
- (IBAction)menuTapped {
NSLog(#"Menu tapped");
CGRect frame = self.browseView.frame;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector( animationDidStop:finished:context: )];
[UIView beginAnimations:#"slideMenu" context:(__bridge void *)(self.browseView)];
if(!menuOpen) {
frame.origin.x = -212;
menuOpen = YES;
table.userInteractionEnabled = NO;
}
else
{
frame.origin.x = 0;
menuOpen = NO;
table.userInteractionEnabled = YES;
}
self.browseView.frame = frame;
[UIView commitAnimations];
}
-(IBAction) sideHome:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
PassportAmericaViewController *homeView = [[PassportAmericaViewController alloc]
initWithNibName:#"PassportAmericaViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:homeView animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideBrowse:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
BrowseViewController *browseView2 = [[BrowseViewController alloc]
initWithNibName:#"BrowseView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:browseView2 animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideBeset:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
BesetCampgroundMapViewController *besetMapView = [[BesetCampgroundMapViewController alloc]
initWithNibName:#"BesetCampgroundMapView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:besetMapView animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideFave:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
FavoritesViewController *faveView = [[FavoritesViewController alloc] initWithNibName:#"FavoritesView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:faveView animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideNew:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
NewCampgroundsViewController *theNewCampView = [[NewCampgroundsViewController alloc]
initWithNibName:#"NewCampgroundsView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:theNewCampView animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideCancelled:(id)sender{
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
menuOpen = NO;
CancelledCampgroundsViewController *cancCampView = [[CancelledCampgroundsViewController alloc]
initWithNibName:#"CancelledCampgroundsView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:cancCampView animated:YES];
table.userInteractionEnabled = YES;
}
-(IBAction) sideCall:(id)sender{
NSLog(#"Calling Passport America...");
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:**********"]];
table.userInteractionEnabled = YES;
}
-(IBAction) sideEmail:(id)sender{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: #"mailto:***************"]];
table.userInteractionEnabled = YES;
}
-(void) searchBarSearchButtonClicked: (UISearchBar *)searchBar {
SearchViewController *search = [[SearchViewController alloc] initWithNibName:#"SearchViewController" bundle:[NSBundle mainBundle]];
NSString *searchText = [[NSString alloc] initWithString:mainSearchBar.text];
search.searchText = searchText;
[self dismissKeyboard];
[self.navigationController pushViewController:search animated:YES];
table.userInteractionEnabled = YES;
menuOpen = NO;
CGRect frame = self.browseView.frame;
frame.origin.x = 0;
self.browseView.frame = frame;
}
-(void) swipeLeft:(UISwipeGestureRecognizer *)recognizer {
if (!menuOpen) {
CGRect frame = self.browseView.frame;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector( animationDidStop:finished:context: )];
[UIView beginAnimations:#"slideMenu" context:(__bridge void *)(self.browseView)];
frame.origin.x = -212;
menuOpen = YES;
self.browseView.frame = frame;
table.userInteractionEnabled = NO;
[UIView commitAnimations];
} else {
//menu already open, do nothing
}
}
-(void) swipeRight:(UISwipeGestureRecognizer *)recognizer {
if (!menuOpen) {
//menu closed, do nothing
} else {
CGRect frame = self.browseView.frame;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector( animationDidStop:finished:context: )];
[UIView beginAnimations:#"slideMenu" context:(__bridge void *)(self.browseView)];
frame.origin.x = 0;
menuOpen = NO;
self.browseView.frame = frame;
table.userInteractionEnabled = YES;
[UIView commitAnimations];
}
}
- (void) viewWillDisappear:(BOOL)animated {
[self.table deselectRowAtIndexPath:[self.table indexPathForSelectedRow] animated:animated];
[super viewWillDisappear:animated];
}
- (void)didReceiveMemoryWarning {
NSLog(#"Memory Warning!");
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
self.table = nil;
self.countriesArray = nil;
self.browseView = nil;
[super viewDidUnload];
}
#end
Determine which cell the swipe takes place in, compute the index path, and call didSelectRowAtIndexPath from your gestureRecognizer code.

Gesture recognizer and UIImageView

I found this code to change the image when it is clicked.
in .h
#interface MyappViewController : UIViewController
{
NSDictionary *ddata;
UIImageView *firstImage;
}
#property(retain,nonatomic) IBOutlet UIImageView *firstImage;
in .m
- (void)viewDidLoad
{
[super viewDidLoad];
firstImage.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:#selector(clickHandler:)];
pgr.delegate = self;
[firstImage addGestureRecognizer:pgr];
[pgr release];
// [self clickHandler:self];
}
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
/* destroy the transition view, set the image first */
UIImageView *transitionImageView = (UIImageView *)context;
self.firstImage.image = transitionImageView.image;
[transitionImageView removeFromSuperview];
transitionImageView = nil;
}
- (void)clickHandler:(id)sender {
/* temporary view for the animation */
NSLog(#"Click Handled ");
UIImageView *transitionImageView = [[UIImageView alloc] initWithFrame:self.firstImage.frame];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[ddata objectForKey:#"pic"]]]];
transitionImageView.image = image;
transitionImageView.alpha = 0.0f;
[self.view addSubview:transitionImageView];
[UIView beginAnimations:#"UpdateImages" context:transitionImageView];
[UIView setAnimationDuration:2.0f];
transitionImageView.alpha = 1.0f;
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView commitAnimations];
}
When I click the image nothing happens, but if I call [self clickHandler:self]; in ViewDidLoad, the image changes. My problem is that the click is not handled when I click the image.
Instead of a UIPinchGestureRecognizer you need to use a UITapGestureRecognizer. Don't forget to set things like the number of taps required and number of fingers either. The docs are very good for gesture recognizers.

How to remove view and redraw it

I have a view on which I can draw. When the user clicks on cancel button, the view is cleared and new Image is drawn in that view. I am posting my code. Can anyone help?
#import "SignatureViewController.h"
#implementation SignatureViewController
#synthesize salesToolBar;
-(void)buttonpressed
{
NSString *allElements = [myarray componentsJoinedByString:#""];
NSLog(#"%#", allElements);}
-(void)buttonclear{
[drawImage removeFromSuperview];
//UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.height, self.view.frame.size.width));
drawImage = [[UIImageView alloc] initWithImage:nil];
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width )];
drawImage.frame = self.view.frame;
[self.view addSubview:drawImage];
self.view.backgroundColor = [UIColor greenColor];
mouseMoved = 0;
//[super viewDidLoad];
}
-(void)buttoncancel{
[[self navigationController] popViewControllerAnimated: YES];
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}
- (void)viewDidLoad {
[super viewDidLoad];
myarray = [[NSMutableArray alloc] init];
CGFloat x = self.view.bounds.size.width / 2.0;
CGFloat y = self.view.bounds.size.height / 2.0;
CGPoint center = CGPointMake(y, x);
// set the new center point
self.view.center = center;
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, -(M_PI / 2.0));
self.view.transform = transform;
self.view.backgroundColor = [UIColor greenColor];
self.title = #"Signature";
[self createToolbar];
NSLog(#"View Did Load Run");
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(#"Self.view.frame.height = %f and width = %f ", self.view.frame.size.height, self.view.frame.size.width);
NSLog(#"View Did Appear Run");
self.navigationController.navigationBarHidden=TRUE;
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
[super viewDidLoad];
}
Sounds like you need to call setNeedsDisplay: on the view. :)