2

我在我的项目中遇到问题我的项目目的是UIImages在开始时添加许多图像,这些图像应该可以拖放,因为我使用UIPanGestureRecognizer但仍然遇到问题请帮助我提前谢谢。

这段代码在我的viewdidload方法中

 UIView *holderView = [[UIView alloc]init];

for (int i = 0; i<=4; i+=1) {

    NSMutableArray * images = [[NSMutableArray alloc]initWithObjects:@"iphone-status-bar.png",@"uiswitch.png",@"NavigationBar.png",@"barbutton.png",@"ios-back-button.png", nil];


    NSString * image_name= [NSString stringWithFormat:@"%@",[images objectAtIndex:i]];

//  NSLog(@"%@",image_name);

    UIImage *image = [UIImage imageNamed:image_name];

    holderView = [[UIView alloc] initWithFrame:CGRectMake(2, i*30, image.size.width, image.size.height)];

    UIImageView *imageview = [[UIImageView alloc] initWithFrame:[holderView frame]];

    imageview.userInteractionEnabled = YES;

    [imageview setImage:image];

    [holderView addSubview:imageview];

    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];

    [panRecognizer setMinimumNumberOfTouches:1];

    [panRecognizer setMaximumNumberOfTouches:1];

    [panRecognizer setDelegate:self];

     [holderView addGestureRecognizer:panRecognizer];


     [self.view addSubview:holderView];
}

手势处理程序是:

-(void)move:(id)sender {

    [self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
    CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {

        firstX = [[sender view] center].x;
        firstY = [[sender view] center].y;
    }

    translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);

    [[sender view] setCenter:translatedPoint];

    if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {

        CGFloat finalX = translatedPoint.x + (.01*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);
        CGFloat finalY = translatedPoint.y + (.01*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);

        if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {

            if(finalX < 0) {

                finalX = 0;
            }

            else if(finalX > 768) {

                finalX = 768;
            }

            if(finalY < 0) {

                finalY = 0;
            }

            else if(finalY > 1024) {

                finalY = 1024;
            }
        }

        else {

            if(finalX < 0) {

                finalX = 0;
            }

            else if(finalX > 1024) {

                finalX = 768;
            }

            if(finalY < 0) {

                finalY = 0;
            }

            else if(finalY > 768) {

                finalY = 1024;
            }
        }

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:.35];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        [[sender view] setCenter:CGPointMake(finalX, finalY)];
        [UIView commitAnimations];
    }
}
4

1 回答 1

0

我个人怀疑holderView逻辑。您正在使用 的垂直偏移量添加到控制器的顶级视图,holderView但是i * 30当您将!更糟糕的是,因为您的手势识别器位于而不是,当您尝试通过点击图像来抓取 时,您通常不会超过您认为的那样,而是针对其他图像之一!imageViewholderViewholderViewi * 30frameholderViewyholderViewimageViewimageViewholderView

假设您喜欢现在的图像布局方式(实际上相距 60.0 分),那么我建议您将其更改i*30i*60.0

  • frame将for 的设置更改imageView[holderView bounds]; 或者,甚至更好,

  • 完全摆脱holderView视图,因为(至少根据您迄今为止共享的内容)它没有增加任何价值,只会使代码复杂化。

顺便说一句,还有一些其他的观察:

  • images数组不需要是可变的,并且您不应该在for循环内重新初始化它。

  • 您可能应该在循环中引用[images count]而不是硬编码。4for

通过这些更改,viewDidLoad代码如下所示:

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

    NSArray *images = [[NSArray alloc]initWithObjects:@"iphone-status-bar.png",@"uiswitch.png",@"NavigationBar.png",@"barbutton.png",@"ios-back-button.png", nil];

    // if you're using a recent version of the compiler, you could simplify that further to just
    //
    // NSArray *images = @[@"iphone-status-bar.png",@"uiswitch.png",@"NavigationBar.png",@"barbutton.png",@"ios-back-button.png"];

    for (int i = 0; i < [images count]; i++) {

        NSString *imageName = [images objectAtIndex:i]; // or you could say `NSString *imageName = images[i];`
        UIImage *image = [UIImage imageNamed:imageName];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        imageView.frame = CGRectMake(2.0, i * 60.0, image.size.width, image.size.height);
        imageView.userInteractionEnabled = YES;
        [self.view addSubview:imageView];

        UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
        panRecognizer.minimumNumberOfTouches = 1;
        panRecognizer.maximumNumberOfTouches = 1;

        [imageView addGestureRecognizer:panRecognizer];
    }
}

move你也可以稍微简化你的日常工作:

-(void)move:(UIPanGestureRecognizer *)gesture {

    static CGPoint originalCenter; // or make this a class ivar; but don't make this a global!

    if (gesture.state == UIGestureRecognizerStateBegan) {

        [gesture.view.superview bringSubviewToFront:gesture.view];
        originalCenter = gesture.view.center;
    }

    CGPoint translation = [gesture translationInView:self.view];
    CGPoint translatedPoint = CGPointMake(originalCenter.x+translation.x, originalCenter.y+translation.y);

    gesture.view.center = translatedPoint;

    if(gesture.state == UIGestureRecognizerStateEnded) {
        CGPoint velocity = [gesture velocityInView:gesture.view];
        translatedPoint.x = MAX(translatedPoint.x + .01 * velocity.x, 0.0);
        translatedPoint.y = MAX(translatedPoint.y + .01 * velocity.y, 0.0);

        if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {

            translatedPoint.x = MIN(translatedPoint.x, 768.0);
            translatedPoint.y = MIN(translatedPoint.y, 1024.0);
        }
        else {

            translatedPoint.x = MIN(translatedPoint.x, 1024.0);
            translatedPoint.y = MIN(translatedPoint.y, 768.0);
        }

        [UIView animateWithDuration:0.35
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             gesture.view.center = translatedPoint;
                         }
                         completion:nil];
    }
}

就个人而言,我讨厌看到硬编码的坐标,所以我可能会进一步将UIGestureRecognizerStateEnded代码简化为:

if(gesture.state == UIGestureRecognizerStateEnded) {
    CGPoint velocity = [gesture velocityInView:gesture.view];
    translatedPoint.x = MAX(translatedPoint.x + .01 * velocity.x, 0.0);
    translatedPoint.y = MAX(translatedPoint.y + .01 * velocity.y, 0.0);
    translatedPoint.x = MIN(translatedPoint.x, gesture.view.superview.bounds.size.width);
    translatedPoint.y = MIN(translatedPoint.y, gesture.view.superview.bounds.size.height);

    [UIView animateWithDuration:0.35
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         gesture.view.center = translatedPoint;
                     }
                     completion:nil];
}
于 2013-04-23T15:27:29.203 回答