iphone::touchesMoved: Move UIImageView inside UIView? - uiview

This is my code:
- (void) touchesBegan: (NSSet *)touches withEvent: (UIEvent *)event {
CGPoint pt = [[touches anyObject] locationInView:self.view];
startLocation = pt;
[super touchesBegan: touches withEvent: event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint pt = [[touches anyObject] locationInView:self.view];
CGRect frame = [self.view frame];
frame.origin.x += pt.x - startLocation.x;
frame.origin.y += pt.y - startLocation.y;
[self.view setFrame:frame];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *v = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 100, 100)];
v.backgroundColor = [UIColor redColor];
UIImageView *imv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"boo2.png"]];
imv.frame = CGRectMake(0, 0, 50, 50);
[v addSubview:imv];
[self.view addSubview: v];
[v release];
UIView *v2 = [[UIView alloc] initWithFrame: CGRectMake(100, 100, 100, 100)];
v2.backgroundColor = [UIColor blueColor];
UIImageView *imv2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"boo2.png"]];
imv2.frame = CGRectMake(0, 0, 50, 50);
[v2 addSubview:imv2];
[self.view addSubview: v2];
[v2 release];
}
What I want to do is to move the UIImageView inside the UIView, not the entire view. But, the code above, when I try to drag, it moves the entire view.
NOTE: The images are return from others functions, not declared in viewdidload. Assume, you cant declare UIImageView variables.

I'm not quite sure what you're trying to do. and I don't know why you put each of the UIImageView's inside a UIView which you put into the view controller's view. You can just as well add the UIImageView's as sub-views of the view controller's view directly.
Nevertheless, from what I can make out it looks like the user must be able to drag the images on the screen around.
If this is the case, I would suggest that you store each one of the UIImageView's in an array. Then, in touchesBegan:withEvent:, you will have to determine which UIImageView is being touched. Getting the CGPoint representing the location in the main view, as you do in your code, is a good start. If you added the UIImageView's directly as sub-views of the main view, you can then compare the coordinates of this CGPoint with the frames of these UIImageView's to determine which one is being pressed.
Then, to allow dragging, you need to save the coordinates of the UIImageView at the beginning of the touch. Then, everytime the touch moves, you can compute the new x-position of the UIImageView as the original x-position, plus the distance moved. That is,
newImageViewX = imageViewStartX + (newTouchX - touchStartX);
and similarly for the y-position.

Related

Create dynamic uiview on double tap

Hello fellow programmers.,
I want to create dynamic UIView of size 100X100 around my double click on Main UIView (Everytime I double click diffrant place). I totally don't have any idea about it. So can't provide any code for it. Anyone can help??
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [[touches allObjects] objectAtIndex: 0];
CGPoint currentPos = [myTouch locationInView: self.view];
NSLog(#"Point in myView: (%f,%f)", currentPos.x, currentPos.y);
UIView*hover = [[UIView alloc] initWithFrame:CGRectMake(currentPos.x - 50, currentPos.y - 50 , 100, 100)];
hover.backgroundColor = [UIColor grayColor];
[self.view addSubview:hover];
}
try this code
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(addDynamicView:)];
self.view.userInteractionEnabled = TRUE;
tapGesture.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:tapGesture];
adding the custom view
- (void)addDynamicView:(UITapGestureRecognizer*)aGesture{
/** add view with specified frame **/
CGRect rect = CGRectMake(10, 10, 100, 100);
UIView *lView = [[UIView alloc] initWithFrame:rect];
lView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lView];
}

Zoom with touches in a custom view in a scrollView. touchesMoved not called

I have a custom view that will pinch zoom, but I'd like to also slide it around in any direction. The zoom works well, and the moving works well, but so far it's just one or the other. The touchesMoved method never gets called.
The scrollView has a subView which the user will touch and move. It will function like a little map. On the subView are several custom labels. I have a tap Gesture recognizer on the labels, which works fine now, and will still need to work when the zoom and moving is corrected.
I also tried [scrollView setScrollEnabled:NO]; and other things, but that didn't allow both to work. How can touches Moved be called? What will I need to do to allow both to work?
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setUserInteractionEnabled:YES];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[scrollView setMinimumZoomScale:.7];
[scrollView setMaximumZoomScale:1.5];
[scrollView setAutoresizesSubviews:YES];
[scrollView setUserInteractionEnabled:YES];
scrollView.delegate = self;
[self.view addSubview:scrollView];
CGRect mapFrame = CGRectMake(0, 0, 300, 300);//temp numbers
subView = [[UIView alloc]initWithFrame:mapFrame];
subView.userInteractionEnabled=YES;
subView.autoresizesSubviews=YES;
[scrollView addSubview:subView];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touchesMoved");
touch = [touches anyObject];
CGPoint location = [touch locationInView:subView];
CGPoint prevLoc = [touch previousLocationInView:subView];
CGPoint origin = subView.frame.origin;
origin.x += (location.x - prevLoc.x);
origin.y += (location.y - prevLoc.y);
CGRect newFrame = subView.frame;
newFrame.origin = origin;
subView.frame = newFrame;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return subView;
}
//label sample
newCity =[[MyCustomClass alloc] initWithFrame:CGRectMake(x, y, 95, 40)];
newCity.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(touchUp:)];
[newCity addGestureRecognizer:tapGesture];
[subView addSubview:newCity];
I'm also getting this in the log and don't know why. "Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] since gesture recognizer is not active.
" I removed the pan gesture recognizer, after that didn't work. I'm using Xcode 4.5.2
My header is
#interface CitiesViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
{
UIView *subView;
}
#property(nonatomic, strong) UIView *subView;
#property(nonatomic, strong) UIScrollView *scrollView;
To solve this I removed the TouchesMoved entirely and used a panGestureRecognizer instead. Hopefully it helps someone.
I added this to my subView:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[pan setDelegate:self];
[subView addGestureRecognizer:pan];
Add this method:
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:subView];
subView.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
}
I never did figure out why that message Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] is still occurring, but this seems to work.

Nested UIScrollViews

I have a mainScrollView scrolling horizontally with photos added to it and mainScrollView's contentSize is set according to the number of photos.
To achieve the effect of scrolling to the end and swiping in a UIView with display info for user, I added the overlayScrollView to mainScrollView's subviews.
overlayScrollView contains the contentView positioned outside the frame.
CGRect frame = self.mainScrollView.frame;
frame.origin.x = CGRectGetWidth(frame) * (count-1);
UIScrollView *overlayScrollView = [[UIScrollView alloc] initWithFrame:frame];
[self.mainScrollView addSubview:overlayScrollView];
// moves contentView one frame beyond
frame.origin.x = CGRectGetWidth(frame);
UIView *contentView = [[UIView alloc] initWithFrame:frame];
contentView.backgroundColor = [UIColor redColor];
[overlayScrollView addSubview:contentView];
overlayScrollView.contentSize = CGSizeMake(overlayScrollView.frame.size.width * 2, overlayScrollView.frame.size.height);
overlayScrollView.pagingEnabled = YES;
I searched through SO on nested UIScrollViews and so subclassed UIScrollView for mainScrollView with the following method:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *child in self.subviews){
if([child isMemberOfClass:[UIScrollView class]])
if(CGRectContainsPoint(child.frame, point))
return child;
}
return self;
}
But it doesn't work. My code could be wrong. hitTest did return child (overlayScrollView) but did not scroll. Any suggestions how to code this?

UIScrollView can zoom, but cant pan

I have a UIScrollView with a UIView inside it, in side the UIView I made a button to add textLabels to it.
and ideally I would want a really big canvas and be able to put text on it and pan and zoom around. however with the UIScrollView it does zoom, but does not pan at all
It seems that when I remove the UIView that i add inside the UIScrollView it works fine.
heres viewDidLoad:
[super viewDidLoad];
CGFloat mainViewWidth = 700;
CGFloat mainViewHeight = 500;
//scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height * kNumberOfPages);
//self.mainScrollView.bounds = CGRectMake(0., 0., 3000, 3000);
self.mainScrollView.scrollsToTop = NO;
self.mainScrollView.delegate = self;
self.mainScrollView.maximumZoomScale = 50.;
self.mainScrollView.minimumZoomScale = .1;
self.mainScrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.mainView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, mainViewWidth, mainViewHeight)];
[self.mainView setUserInteractionEnabled:NO];
self.mainView.backgroundColor = [[UIColor alloc] initWithRed:0.82110049709463495
green:1
blue:0.95704295882687884
alpha:1];
[self.mainScrollView setContentSize:CGSizeMake(5000, 5000)];
[self.mainScrollView insertSubview:self.mainView atIndex:0];
Edit:
Heres the all I have for UIScrollViewDelegate
#pragma mark - Scroll View Delegate
- (void)scrollViewDidScroll:(UIScrollView *)sender {
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
//
return self.mainView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)zoomedScrollView withView:(UIView *)view atScale:(float)scale
{
}
I just went through this exact same dilemma.
My UIScrollView exists within the storyboard, and if I add a UIView (containerView) within that storyboard to the UIScrollView, the image fails to pan. And all sorts of other centering weirdness occurs too.
But if I do it through code:
// Set up the image we want to scroll & zoom
UIImage *image = [UIImage imageNamed:#"plan-150ppi.jpg"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.containerView = [[UIView alloc] initWithFrame:self.imageView.frame];
[self.containerView addSubview:self.imageView];
[self.scrollView addSubview:self.containerView];
// Tell the scroll view the size of the contents
self.scrollView.contentSize = self.containerView.frame.size;
... then it works just fine.

UIScrollView with multiple subViews

I have a UIScrollView with many other subviews inside it. Most of the subviews are UITextView's and when they are all loaded, the scrolling and everything is fine. But for one of the views, I am loading a UIView with a MKMapView and a UITextView inside of it. When the user wants to scroll the UIScrollView, they cannot touch the UIView or its contents. I cannot set setUserInteractionEnabled to NO because I need the user to be able to click on the MKMapView and then go to another UIViewController for the map. Are there any suggestions regarding this? I have my code for the above below:
CGRect dealDescRect = CGRectMake(10, 10, delegate.scrollView.frame.size.width - 22 - 20, 120);
mapView = [[MKMapView alloc] initWithFrame:dealDescRect];
mapView.layer.cornerRadius = cornerRadius;
mapView.scrollEnabled = NO;
mapView.zoomEnabled = NO;
BOOL result = [self loadAddressIntoMap];
if (result == TRUE) {
UITapGestureRecognizer* recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[mapView addGestureRecognizer:recognizer];
}
UITextView *addressTextView = [self generateTextView:addressText :5];
addressTextView.editable = NO;
[addressTextView setFont:[UIFont systemFontOfSize:fontSize]];
[addressTextView setUserInteractionEnabled:NO];
CGRect addressTextViewFrame = addressTextView.frame;
addressTextViewFrame.origin.x = 0;
addressTextViewFrame.origin.y = 130;
addressTextViewFrame.size.height = addressTextView.contentSize.height + 15;
addressTextView.frame = addressTextViewFrame;
CGRect viewRect = CGRectMake(10, 145, delegate.scrollView.frame.size.width - 22, addressTextView.contentSize.height + 135);
viewRect.origin.x = 11;
viewRect.origin.y = startTop;
UIView *view = [[UIView alloc] initWithFrame:viewRect];
view.layer.cornerRadius = cornerRadius;
[view setBackgroundColor:[UIColor whiteColor]];
[view addSubview:mapView];
[view addSubview:addressTextView];
EDIT
For some weird reason, if I change the UIView to a UITextView, it works! Not sure what the real solution here is though. I just disable editing.
If it were me, instead of using gesture recognizers to watch for a tap on the map I'd create a UIButton of a custom type (UIButtonTypeCustom) and give it no background and no text, and place it on top of the map with the same frame as the map.
This has the benefit of preventing the user from interacting with the map, moving to the next page as you want and if the user starts scrolling even when over the map they are able to.

Resources