I am using Apple code for just zoom the UIImageView on taps and gestures. But its not work ?
Please see this Apple's link apple code for image zooming by taps and gestures
-(void)veiwDidLoad
{
[super viewDidLoad];// Edited my self
imageView.userInteractionEnabled = YES; // Edited my self
//All code below same.... like Apple's code
// set the tag for the image view
[imageView setTag:ZOOM_VIEW_TAG];
// add gesture recognizers to the image view
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
[imageView addGestureRecognizer:singleTap];
[imageView addGestureRecognizer:doubleTap];
[imageView addGestureRecognizer:twoFingerTap];
[singleTap release];
[doubleTap release];
[twoFingerTap release];
// calculate minimum scale to perfectly fit image width, and begin at that scale
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width;
[imageScrollView setMinimumZoomScale:minimumScale];
[imageScrollView setZoomScale:minimumScale];
}
Make sure that you set your imageView to be userInteractionEnabled = YES; .. its assign to NO by default.
change the function name from
-(void) veiwDidLoad
to
-(void) viewDidLoad
I has a problem like that as well, does that fix it?
Related
I have a blank screen on which i click camera button and take photo and than that photo appears on my blank screen as a UIVIew and i'm adding multiple images from Camera to blank screen. The problem is sometimes i can add multiple images on blank screen but sometimes when i capture image and than all images on blank screen disappear and just shows the current image.
And in LOG. it show me Received memory warning.
this is my code. i think i m now releasing my objects properly. but when i am adding [object release] in the end my app crashes.
-(void)AddImagesToCanvasWithGesture{
if(imageFromPicker.size.width > imageFromPicker.size.height || imageFromPicker.size.width == imageFromPicker.size.height)
{
holderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 180, 160)];
}
else{
holderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 160, 240)];
}
UIImageView *imageview = [[[UIImageView alloc] initWithFrame:[holderView frame]];
[imageview setImage:imageFromPicker];
//[imageview setTag:101];
//[holderView setTag:102];
//NSLog(#"Tag By Default %d",(arc4random()%100)+10);
[holderView setTag:(int)objectDelegate.tagForHolderView];
[imageview setTag:((int)objectDelegate.tagForHolderView)+1];
[holderView addSubview:imageview];
//[imageview canBecomeFirstResponder];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[holderView addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[holderView addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[holderView addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[holderView addGestureRecognizer:tapRecognizer];
UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
[holderView addGestureRecognizer:gestureRecognizer];
[holderView.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[holderView.layer setBorderWidth: 3.0];
[self.view addSubview:holderView];
objectDelegate.tagForHolderView+=2;
for(UIButton *b in self.view.subviews) {
if([b isKindOfClass:[UIButton class]]) {
[self.view bringSubviewToFront:b];
}
[self.view sendSubviewToBack:imageViewForBackground];
//[holderView setHidden:YES];
}
}
how can i release them and where should i call the release method.
From the code snippet you have added above, it's obvious the you are not releasing objects properly. You own every object that you init or retain or copy and you are responsible to release them unless you are using ARC. (The code above is fine for ARC).
You have ownership of all the gesture recognizers and image view and you should release them as soon as you no longer need them. For instance... imageView object must be released after
[holderView addSubview:imageview];
and
pinchRecognizer should be released right after
[holderView addGestureRecognizer:pinchRecognizer];
Same goes for other gesture recognizers.
I guess you have similar kind of problems in other parts of your code too and eventually the app receives memory warning.
When you have a memory problem, if you have a method named
- (void)didReceiveMemoryWarning
it will get called and allow you to free up space. If you are using ARC, just set your UIImageView to nil, if not, call:
[imageview release];
I'm looking at Apple's example code from the ScrollViewSuite. I must be doing something wrong in comparison. In their RootViewController, they do:
- (void)loadView {
[super loadView];
// set the tag for the image view
[imageView setTag:ZOOM_VIEW_TAG];
// add gesture recognizers to the image view
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
[imageView addGestureRecognizer:singleTap];
[imageView addGestureRecognizer:doubleTap];
[imageView addGestureRecognizer:twoFingerTap];
[singleTap release];
[doubleTap release];
[twoFingerTap release];
// calculate minimum scale to perfectly fit image width, and begin at that scale
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width;
[imageScrollView setMinimumZoomScale:minimumScale];
[imageScrollView setZoomScale:minimumScale];
}
In IB, they have their imageView as a subView of the imageScrollView. My .xib is set up the same way. I put this code in my viewDidLoad instead of loadView. I do not get any calls when I double tap on my imageView. I'm wondering why. Here is my version of what they did:
- (void)viewDidLoad {
[self updateOnScreenImages]; // this is where my imageView.image property gets set
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTap.numberOfTapsRequired = 2;
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTouchesRequired:2];
[self.imageView addGestureRecognizer:doubleTap];
[self.imageView addGestureRecognizer:twoFingerTap];
[doubleTap release];
[twoFingerTap release];
}
Is there something I am doing wrong compared to what Apple is doing? The logic seems pretty similar to me. But I'm not getting my callbacks when I double tap. I tried adding the gestures to the self.scrollView as well, but that doesn't work either. Thoughts? Thanks!
Try to add:
self.imageView.userInteractionEnabled = YES;
by default UIImageViews have that property set to NO
(apple may have changed it in XIB file, and you may have lost that...)
#import "RootViewController.h"
#define ZOOM_VIEW_TAG 100
#define ZOOM_STEP 1.5
#interface RootViewController (UtilityMethods)
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center;
#end
#implementation RootViewController
#synthesize imageScrollView, imageView, mySlider;
- (IBAction) sliderValueChanged:(UISlider *)sender {
mySlider.value = [NSString stringWithFormat:imageScrollView.[sender value]];
//mySlider.value = [NSString stringWithFormat:#" %.1f", [sender value]];
//myTextField.text = [NSString stringWithFormat:#" %.1f", [sender value]];
}
- (void)loadView {
[super loadView];
// set the tag for the image view
[imageView setTag:ZOOM_VIEW_TAG];
// add gesture recognizers to the image view
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
[imageView addGestureRecognizer:singleTap];
[imageView addGestureRecognizer:doubleTap];
[imageView addGestureRecognizer:twoFingerTap];
[singleTap release];
[doubleTap release];
[twoFingerTap release];
// calculate minimum scale to perfectly fit image width, and begin at that scale
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width;
[imageScrollView setMinimumZoomScale:minimumScale];
[imageScrollView setZoomScale:minimumScale];
}
- (void)viewDidUnload {
self.imageScrollView = nil;
self.imageView = nil;
}
- (void)dealloc {
[imageScrollView release];
[imageView release];
[super dealloc];
}
#pragma mark UIScrollViewDelegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [imageScrollView viewWithTag:ZOOM_VIEW_TAG];
}
/************************************** NOTE **************************************/
/* The following delegate method works around a known bug in zoomToRect:animated: */
/* In the next release after 3.0 this workaround will no longer be necessary */
/**********************************************************************************/
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
[scrollView setZoomScale:scale+0.01 animated:NO];
[scrollView setZoomScale:scale animated:NO];
}
#pragma mark TapDetectingImageViewDelegate methods
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {
// single tap does nothing for now
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// double tap zooms in
float newScale = [imageScrollView zoomScale] * ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[imageScrollView zoomToRect:zoomRect animated:YES];
}
- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer {
// two-finger tap zooms out
float newScale = [imageScrollView zoomScale] / ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[imageScrollView zoomToRect:zoomRect animated:YES];
}
#pragma mark Utility methods
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [imageScrollView frame].size.height / scale;
zoomRect.size.width = [imageScrollView frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
#end
all of you. I have been working on map view but i unable solve pinch and tap detection problem.I want to detect pinch and tap in map view.
I have tried following code in iPhone MapView
UITapGestureRecognizer *Tap= [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(checktap)];
[self.mapView addGestureRecognizer:Tap];
[Tap release];
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(checkpinch)];
[self.mapView addGestureRecognizer:pinch];
[pinch release];
Where tap is working but pinch detection is not working.
Please help me.
Thanks in Advanced.
Add following code in your view did load and add Gesture recognizer delegate in you .h file.
Enjoy...:)
[self.view insertSubview:mapView atIndex:0];
//Gesture reconizer
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(checkpinch)];
[pinch setDelegate:self];
[pinch setDelaysTouchesBegan:YES];
[self.mapView addGestureRecognizer:pinch];
[pinch release];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(checktap)];
[singleTap setDelegate:self];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired =2;
[self.mapView addGestureRecognizer:singleTap];
[singleTap release];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(checktap)];
[doubleTap setDelegate:self];
doubleTap.numberOfTapsRequired = 2;
doubleTap.numberOfTouchesRequired =1;
[self.mapView addGestureRecognizer:doubleTap];
[doubleTap release];
For UITapGestureRecognizer, you can set number of taps required to control the recognition of the UITapGestureRecognizer. If you set numberOfTapsRequired to 2 and user taps only once, then the UITapGestureRecognizer won't be triggered.
My question is How about for UIPanGestureRecognizer? How to control its recognition?
I have a view. Once I set a UIPanGestureRecognizer to it, any dragging will trigger the action. But what I want is only the dragging in X-axis. And for non-X-axis dragging, all touch events should be sent to other views underneath.
How can I do it?
THanks
Set its delegate and implement
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
Then use
- (CGPoint)velocityInView:(UIView *)view;
on the gesture recogniser to calculate whether the gesture recognizer should handle it or not.
Check How to stop UIPanGestureRecognizer when object moved to certain frame. It may help you.
UIView *holderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
UIImageView *imageview = [[UIImageView alloc] initWithFrame:[holderView frame]];
[imageview setImage:image];
[holderView addSubview:imageview];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[holderView addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[holderView addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[holderView addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[holderView addGestureRecognizer:tapRecognizer];
[self.view addSubview:holderView];
Raees
Assume that your gestureRecognizer triggers the action _panRecogPanned below. You can see how the center of a subview ( the view that carries the gesture recognizer itself) moves following the transition. To disable panning on y axis, you simply set the center as the calculated new center, whereas the translation.y is omitted.
To move other subviews on the y axis, get their frame, update their origin.x property and reset the frame, they should follow your finger only on the y axis.
- (IBAction)_panRecogPanned:(id)sender{
CGPoint translation = [_panRecog translationInView:_statementFilterView];
//This subview only moves horizontally
_panRecog.view.center = CGPointMake(translation.x + _panRecog.view.center.x, _panRecog.view.center.y);
//This subview only moves vertically
CGRect newFrame = anotherSubview.frame;
newFrame.origin.y = anotherSubview.frame.origin.y + translation.y;
anotherSubview.frame = newFrame;
[_panRecog setTranslation:CGPointMake(0, 0) inView:self.view];
}
I have a UIScrollView with multiple UIImageViews in it created like this.
frame = [[UIImageView alloc] initWithImage:bg];
frame.frame = CGRectMake(FRAME_SEPARATOR + numPage*1024 + numColumn*(FRAME_SEPARATOR+230), 10 +numRow*(FRAME_SEPARATOR+145), 230, 145);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[frame addGestureRecognizer:tap];
[tap release];
[scroll addSubView:frame];
The problem is that imageTapped is not being called when tapping over an image.
If I add the gesture recognizer to the scrollview like this:
UITapGestureRecognizer *tap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[scroll addGestureRecognizer:tap];
[tap release];
imageTapped is called.
How can I detect the taps over the UIImageViews?
Thanks
Make sure userInteractionEnabled is set to YES on the UIImageView:
frame.userInteractionEnabled = YES;
I'd also recommend using a different name for the UIImageView variable (eg. imageView instead of frame). Otherwise, you can easily confuse it with the view's frame property.