Gesture recognizer within a UIScrollview

2019-04-17 06:02发布

问题:

I've got a scroller within my view and got several images inside this scroller.

I'd like to drag and drop these images out (and into) my scroller. I implemented a LongPressGestureRecognizer.

I also would like to know (by code) which image got longpressed. I thought I fixed this last one by using CGRectContainsPoint. However my code is not reacting to the CGRectContainsPoint. It still Logs "fail".

- (void)viewDidLoad{

    //scroller properties
    scroller.contentSize = CGSizeMake(1300, 130);
    scroller.scrollEnabled = YES;
    scroller.directionalLockEnabled =YES;
    scroller.frame = CGRectMake(0, 874, 768, 130);

    UILongPressGestureRecognizer *longPress =
    [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];

    [image1 addGestureRecognizer:longPress];
    [image2 addGestureRecognizer:longPress];
    [image3 addGestureRecognizer:longPress];
    [longPress release];

}

-(void)longPressed:(UILongPressGestureRecognizer *)sender {


    CGPoint location = [sender locationInView:self.view];

    if(CGRectContainsPoint(image1.frame,  location)) {
        NSLog(@"image1 has been longpressed");
        // do something
    }

    if(CGRectContainsPoint(image2.frame,  location)) {
        NSLog(@"image2 has been longpressed");
        // do something
    }

    if(CGRectContainsPoint(image3.frame,  location)) {
        NSLog(@"image3 has been longpressed");
        // do something


    }

         else {
                 NSLog(@"fail");
}

Has someone got experience with this LongPressGestureRecognizer and the number of images that can respond to this function?


i did succeeded implementing the two gesturerecognizers. So the images within my scroller are now draggable. However it limits itself inside the scrollview. I'd like to have some function which takes care of bringing the images in front of the scrollview, so that I can drag my images out of my scrollview.

Within my viewDidLoad method I implemented

[scroller addSubview:image1];
[scroller addSubview:image2];
[scroller addSubview:image3];

[[self view] addSubview:scroller];

and within my longPressed method I implemented

[image1 bringSubviewToFront:self.view];

Someone has good Tips? They are greatly appreciated!

回答1:

Add a scrollview and create one IBOutlet

Add three images to your project in this answer i use the names image1.png, image2.png and image3.png

And finally here is the code

- (void) viewDidLoad{
        [super viewDidLoad];

        for (int i=1; i<=3; i++) {
            NSString *file = [NSString stringWithFormat:@"image%d.png", i];
            UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:file]];
            imageView.frame = CGRectMake(i * 200, 0, 200, 200);
            imageView.userInteractionEnabled = YES;
            imageView.tag = i;
                      
            UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer              alloc] initWithTarget:self action:@selector(longPress:)];
           
            [thumbView addGestureRecognizer:recognizer];
            [scrollView addSubview:thumbView];
        }
    }    

-(void)longPress: (UILongPressGestureRecognizer *)recognizer
{
        UIView *view  = recognizer.view;
        int index = view.tag;
        NSLog(@"image pressed : %i", índex);
}

With this approach you will be able to create 3 imageViews and add to them a gesture recognizer with less code and tell you wich imageView was longPressed

But if you want to drag the imageView UILongPressGestureRecognizer is not going to work for you, for that task you should use UIPanGestureRecognizer

If you want to drag the imageView out of the scrollView you can mimic that effect Removing/hiding the imageView from scrollView and add a imageView with the same image exactly where was the imageView you hide/remove into the view you want to drag the imageView

Is more a visual effect but works



回答2:

Just modify your class like below:

 @implementation longGestureViewController

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView 
{
    UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];

    self.view = view;
    self.view.tag = 100;
    [view release];

    mImageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 10.0, 100.0, 120.0)];
    mImageView1.image = [UIImage imageNamed:@"tile07.png"];
    [self.view addSubview:mImageView1];
    mImageView1.userInteractionEnabled = YES;
    mImageView1.tag = 1;
    [mImageView1 release];

    mImageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(120.0, 10.0, 100.0, 120.0)];
    mImageView2.image = [UIImage imageNamed:@"tile08.png"];
    mImageView2.userInteractionEnabled = YES;
    mImageView2.tag = 2;
    [self.view addSubview:mImageView2];
    [mImageView2 release];

    mImageView3 = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 140.0, 100.0, 120.0)];
    mImageView3.image = [UIImage imageNamed:@"tile09.png"];
    mImageView3.tag = 3;
    mImageView3.userInteractionEnabled = YES;
    [self.view addSubview:mImageView3];
    [mImageView3 release];
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
{
    [super viewDidLoad];

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];

    [mImageView1 addGestureRecognizer:longPress];
    [longPress release];

    longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];

    [mImageView2 addGestureRecognizer:longPress];
    [longPress release];

    longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];

    [mImageView3 addGestureRecognizer:longPress];
    [longPress release];
}

-(void)longPressed:(UILongPressGestureRecognizer *)sender 
{
    CGPoint location = [sender locationInView:self.view];
    UIView *view = [self.view hitTest:location withEvent:UIEventTypeTouches];
    NSLog(@"%d", view.tag);
}


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc 
{
    [super dealloc];
}