我在项目中遇到问题我的项目目的是在开始时添加许多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];
}
}
答案 0 :(得分:0)
我个人怀疑holderView
逻辑。您使用holderView
的垂直偏移量将i * 30
添加到控制器的顶级视图中,但是当您将imageView
添加到holderView
时,您正在抵消它在holderView
之后再次i * 30
(因为您使用frame
的{{1}},其中有holderView
个偏移量)!更糟糕的是,因为您的手势识别器位于y
而不是holderView
,当您尝试通过点击图像抓住imageView
时,您通常不会超过你认为自己是imageView
,而是其他一个图像中的一个!
假设您喜欢现在布置图像的方式(相距60.0分),那么我建议您将holderView
更改为i*30
并且:或者
将i*60.0
的{{1}}设置更改为frame
;或者,甚至更好,
完全摆脱了imageView
个观点,因为(至少基于你目前所分享的内容)它没有增加任何价值,只会使代码复杂化。
另外,还有一些其他观察结果:
[holderView bounds]
数组不需要是可变的,您不应该在holderView
循环内重新初始化它。
您可能应该在images
循环中引用for
而不是硬编码[images count]
。
通过这些更改,4
代码如下所示:
for
您也可以简化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];
}
}