iOS:TapGestureRecognizer问题

所以我有一个应用程序,就像一个照片库,我正在实现用户删除图像的能力。 这里是设置:我有9 UIImageViews,imageView,imageView2等。我也有一个“编辑”button,tapGesture行动方法。 我将一个Tap Gesture识别器拖到IB的视图中,并将其附加到每个UIImageView。 我还将tapGesture操作方法附加到每个UIImageView。 理想情况下,我希望方法只有在按下“编辑”button时才能激活。 当用户点击编辑,然后点击他们想要删除的图片,我想要一个UIAlertView出现,问他们是否确定要删除它。 这是我正在使用的代码:

- (IBAction)editButtonPressed:(id)sender { editButton.hidden = YES; backToGalleryButton.hidden = NO; tapToDeleteLabel.hidden = NO; } - (IBAction)tapGesture:(UITapGestureRecognizer*)gesture { UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:@"Delete" message:@"Are you sure you want to delete this photo?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; [deleteAlertView show]; if (buttonIndex != [alertView cancelButtonIndex]) { UIImageView *view = [self.UIImageView]; if (view) { [self.array removeObject:view]; } CGPoint tapLocation = [gesture locationInView: self.view]; for (UIImageView *imageView in self.view.subviews) { if (CGRectContainsPoint(self.UIImageView.frame, tapLocation)) { ((UIImageView *)[self.view]).image =nil; } } [self.user setObject:self.array forKey:@"images"]; } } 

这段代码显然充满了错误:在这一行上使用“未声明的标识符button索引”: if (buttonIndex != [alertView cancelButtonIndex])

UIImageView *view = [self.UIImageView];在此行上的“属性UIImageView未findtypes的PhotoViewController对象”

和这个行上的“Expected identifier” ((UIImageView *)[self.view]).image =nil;

我对编程非常陌生,我很惊讶我甚至做到了这一点。 所以,我只是想弄清楚我需要如何编辑我的代码,以便错误消失,并且只要轻按9个图像视图中的一个,就可以使用它,而且这个方法只会在编辑button被先推。 我以前使用的标签,它的工作很好,但我通过NSData保存图像,所以我不能再使用标签。 任何帮助非常感谢,谢谢!

首先,您不想将轻击手势附加到图像视图。 另外,如果你要有超过9个图像,你可能需要一个滚动视图,或单独处理滚动。 首先,移除该手势识别器及其所有连接。

接下来,确定您将用作画廊canvas的视图types。 一个简单的视图,或一个滚动视图,或其他…现在并不重要,只是为了得到它的工作。 你想按CTRL-拖动视图到你的接口定义,所以它会放下视图的IBOutlet(这样你可以在代码中引用它)。

你将把你的ImageView放到我刚才提到的视图上。

你可以有一个手势识别器的内部标志,但它也有一个属性,使用可以启用/禁用它,只要你想。 因此,您可以相当容易地使其处于活动状态。

所有你想要做的就是把一个轻敲手势识别器放到你的控制器上,并把它连接到控制器的实现部分。 它将生成一个用于处理识别器的存根。 它将解释控制器的“普遍”的轻敲,并且在视图上进行轻敲时调用您的代码。

一些更多的代码…

在滚动视图中为“新”图像创build一个框架。

 - (CGRect)frameForData:(MyData*)data atIndex:(NSUInteger)idx { CGPoint topLeft; int row = idx / 4; int col = idx % 4; topLeft.x = (col+1)*HORIZ_SPACING + THUMBNAIL_WIDTH * (col); topLeft.y = (row+1)*VERT_SPACING + THUMBNAIL_HEIGHT * (row); return CGRectMake(topLeft.x, topLeft.y, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); } 

为每个元数据创build一个图像视图,并创build一个小边框。

 - (UIImageView*)createImageViewFor:(MetaData*)metadata { UIImageView *imageView = [[UIImageView alloc] initWithImage:metadata.lastImage]; imageView.frame = CGRectMake(0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);; imageView.layer.borderColor = [[UIColor blackColor] CGColor]; imageView.layer.borderWidth = 2.0; imageView.userInteractionEnabled = YES; return imageView; } 

这是视图被创build并添加到父…

  imageView = [self createImageViewFor:metadata]; //[data.imageView sizeToFit]; // Make sure the scrollView contentSize represents the data CGRect lastFrame = [self frameForData:data atIndex:self.data.count-1]; CGFloat newHeight = lastFrame.origin.y + lastFrame.size.height; if (self.bookshelfScrollView.contentSize.height < newHeight) { CGSize newSize = self.bookshelfScrollView.contentSize; newSize.height = newHeight; self.bookshelfScrollView.contentSize = newSize; } [self.bookshelfScrollView addSubview:data.imageView]; 

因此,您只需创build每个框架,将它们添加到视图中,并且唯一要做的就是启用用户交互,否则滚动视图不允许通过手势。

好吧…看着你发布的代码…因为你没有说出什么问题…很难说…下面是你的代码…我的意见是,好吧,评论.. 。

 - (IBAction)editButtonPressed:(id)sender { editButton.hidden = YES; backToGalleryButton.hidden = NO; tapToDeleteLabel.hidden = NO; } - (IBAction)tapGesture:(UITapGestureRecognizer*)gesture { // I don't think I'd do this here, but it shouldn't cause "problems." UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:@"Delete" message:@"Are you sure you want to delete this photo?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; [deleteAlertView show]; // In your controller, you have the main view, which is the view // on which you added your UIViews. You need that view. Add it as an IBOutlet // You should know how to do that... ctrl-drag to the class INTERFACE source. // Assuming you name it "galleryView" // Take the tap location from the gesture, and make sure it is in the // coordinate space of the view. Loop through all the imageViews and // find the one that contains the point where the finger was taped. // Then, "remove" that one from its superview... CGPoint tapLocation = [gesture locationInView: self.galleryView]; for (UIImageView *imageView in self.galleryView.subviews) { if (CGRectContainsPoint(imageView.frame, tapLocation)) { [imageView removeFromSuperview]; } } } 

就我个人而言,在我的小照片库中,我绕过了所有的手势识别器的东西,用UIButton控件代替UIImageView控件,设置button的图像属性,就像你为UIImageView 。 它看起来是一样的,但是你可以免费获得缩略图的function,根本不需要任何手势。

所以,我的观点只是有一个UIScrollView ,其中我编程添加我的图像作为button与图像设置为button控制,例如:

 - (void)loadImages { listOfImages = [ImageData newArrayOfImagesForGallery:nil]; // some variables to control where I put my thumbnails (which happen to be 76 x 76px) int const imageWidth = 76; int const imageHeight = imageWidth; NSInteger imagesPerRow; NSInteger imagePadding; NSInteger cellWidth; NSInteger cellHeight; // some variables to keep track of where I am as I load in my images int row = 0; int column = 0; int index = 0; // add images to navigation bar for (ImageData *item in listOfImages) { // figure out what row and column I'm on imagesPerRow = self.view.frame.size.width / (imageWidth + 2); imagePadding = (self.view.frame.size.width - imageWidth*imagesPerRow) / (imagesPerRow + 1); cellWidth = imageWidth + imagePadding; cellHeight = imageHeight + imagePadding; // this is how I happen to grab my UIImage ... this will vary by implementation UIImage *thumb = [item imageThumbnail]; // assuming I found it... if (thumb) { // create my button and put my thumbnail image in it UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(column * cellWidth + imagePadding, row * cellHeight + imagePadding, imageWidth, imageHeight); [button setImage:thumb forState:UIControlStateNormal]; [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; button.tag = index++; [[button imageView] setContentMode:UIViewContentModeScaleAspectFit]; // add it to my view [scrollView addSubview:button]; // increment my column (and if necessary row) counters, making my scrollview larger if I need to) if (++column == imagesPerRow) { column = 0; row++; [scrollView setContentSize:CGSizeMake(self.view.frame.size.width, (row+1) * cellHeight + imagePadding)]; } } } } // I also have this in case the user changes orientation, so I'll move my images around if I need to - (void)rearrangeImages { if (!listOfImages) { [self loadImages]; return; } // a few varibles to keep track of where I am int const imageWidth = 76; int const imagesPerRow = self.view.frame.size.width / (imageWidth + 2); int const imageHeight = imageWidth; int const imagePadding = (self.view.frame.size.width - imageWidth*imagesPerRow) / (imagesPerRow + 1); int const cellWidth = imageWidth + imagePadding; int const cellHeight = imageHeight + imagePadding; NSArray *buttons = [[NSArray alloc] initWithArray:[scrollView subviews]]; int row; int column; int index; CGRect newFrame; // iterate through the buttons for (UIView *button in buttons) { index = [button tag]; if ([button isKindOfClass:[UIButton class]] && index < [listOfImages count]) { // figure out where the button should go row = floor(index / imagesPerRow); column = index % imagesPerRow; newFrame = CGRectMake(column * cellWidth + imagePadding, row * cellHeight + imagePadding, imageWidth, imageHeight); // if we need to move it, then animation the moving if (button.frame.origin.x != newFrame.origin.x || button.frame.origin.y != newFrame.origin.y) { [UIView animateWithDuration:0.33 animations:^{ [button setFrame:newFrame]; }]; } } } NSInteger numberOfRows = floor(([listOfImages count] - 1) / imagesPerRow) + 1; [scrollView setContentSize:CGSizeMake(self.view.frame.size.width, numberOfRows * cellHeight + imagePadding)]; } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [self rearrangeImages]; } 

希望这给你一个想法,你如何以编程方式添加一个UIButton作为一个画廊中的图像。 我试图编辑这个dynamic,所以我提前道歉,如果我介绍了在这个过程中的任何错误,但它应该给你一个你可以想象的做的感觉…我删除了我的代码做到这一点单独的GCD队列(我这样做,因为我有近100个图像,这样做主队列太慢了。)

无论如何,你可以创build你的buttonClicked方法来显示你的UIAlertView

 - (void)buttonClicked:(UIButton *)sender { if (inEditMode) { // create your UIAlterView using [sender tag] to know which image you tapped on } } 

最后,在UIAlertView有两个button,但是您似乎没有检查用户点击了哪个button。 你的视图控制器应该是一个UIAlterViewDelegate ,其中你已经定义了你的alertView:clickedButtonAtIndex ,它将完成你的实际编辑步骤。

 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { // ok, will do what I need to do with whatever the user tapped in my alertview } 

我能想到的最简单的事情就是默认禁用手势,一旦编辑button被击中,手势就会启用。 这样,只有在“编辑”模式下,图片才会响应轻击手势识别器。