[英]iOS: TapGestureRecognizer Issues
所以我有一個行為類似於照片庫的應用程序,並且我正在實現用戶刪除圖像的功能。 這是設置:我有 9 個 UIImageView、imageView、imageView2 等。我還有一個“編輯”按鈕和一個 tapGesture 操作方法。 我將 Tap Gesture Recognizer 拖到我在 IB 中的視圖上,並將其附加到每個 UIImageView。 我還將 tapGesture 操作方法附加到每個 UIImageView。 理想情況下,我希望該方法僅在按下“編輯”按鈕時才激活。 當用戶點擊編輯,然后點擊他們要刪除的圖片時,我希望出現一個 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"];
}
}
這段代碼顯然充滿了錯誤:“使用未聲明的標識符按鈕索引”這一行: if (buttonIndex != [alertView cancelButtonIndex])
“屬性 UIImageView 在類型 PhotoViewController 的 object 上找不到”這一行UIImageView *view = [self.UIImageView];
以及這一行的“預期標識符” ((UIImageView *)[self.view]).image =nil;
我對編程很陌生,我很驚訝我能做到這一點。 所以,我只是想弄清楚我需要如何編輯我的代碼,以便消除錯誤 go,並且只要點擊 9 個圖像視圖之一就可以使用它,並且只有在首先按下編輯按鈕。 我之前使用過標簽,效果很好,但我通過 NSData 保存圖像,所以我不能再使用標簽了。 非常感謝任何幫助,謝謝!
首先,您不想將點擊手勢附加到圖像視圖。 此外,如果您要擁有超過 9 張圖像,您可能需要滾動視圖,或單獨處理滾動。 首先,刪除該手勢識別器及其所有連接。
接下來,確定您將使用哪種類型的視圖作為您的圖庫 canvas。一個簡單的視圖,或一個滾動視圖,或任何...現在並不重要,只是讓它工作。 您想要將該視圖按住 trl 並拖動到您的接口定義中,因此它會為該視圖刪除一個 IBOutlet(這樣您就可以在代碼中引用它)。
您將把您的 ImageView 放到我剛才提到的視圖上。
您可以為手勢識別器設置一個內部標志,但它也有一個屬性,您可以隨時啟用/禁用它。 因此,您可以很容易地使其處於活動/非活動狀態。
您要做的就是將單個點擊手勢識別器放到您的 controller 上,並將其連接到 controller 的實現部分。它將生成一個用於處理識別器的存根。 它將“一般”解釋 controller 的點擊,並在視圖上進行點擊時調用您的代碼。
一些更多的代碼...
在滾動視圖中為“新”圖像創建一個框架。
- (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);
}
為每個元數據和一個小邊框創建一個圖像視圖。
- (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;
}
這是創建視圖並將其添加到父視圖的地方...
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];
因此,您只需創建每個框架,將它們添加到視圖中,您唯一需要做的就是在它們上啟用用戶交互,否則滾動視圖將不允許手勢通過。
好的...查看您發布的代碼...因為您沒有說它有什么問題...很難說...下面是您的代碼...我的評論是,好吧,評論.. .
- (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];
}
}
}
就個人而言,在我的小照片庫中,我通過將UIImageView
控件替換為UIButton
控件來繞過所有手勢識別器,像為UIImageView
一樣設置按鈕的圖像屬性。 它看起來一模一樣,但是你可以免費獲得點擊縮略圖的功能,根本不需要任何手勢。
因此,我的視圖只有一個UIScrollView
,我以編程方式將我的圖像添加為按鈕,並為按鈕控件設置圖像,例如:
- (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
以充當圖庫中的圖像。 我試圖即時編輯它,所以如果我在這個過程中引入了任何錯誤,我會提前道歉,但它應該讓你了解你可以想象的事情......我刪除了我的代碼以在單獨的 GCD 隊列(我這樣做是因為我有將近 100 張圖像,並且在主隊列上這樣做太慢了。)
無論如何,您可以創建buttonClicked
方法來顯示UIAlertView
。
- (void)buttonClicked:(UIButton *)sender
{
if (inEditMode)
{
// create your UIAlterView using [sender tag] to know which image you tapped on
}
}
最后,您的UIAlertView
上有兩個按鈕,但您似乎沒有檢查用戶單擊了哪個按鈕。 您的視圖 controller 應該是一個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
}
我能想到的最簡單的事情就是默認禁用手勢,然后在按下編輯按鈕后啟用手勢。 這樣,如果圖片處於“編輯”模式,則圖片只會響應點擊手勢識別器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.