2012-04-10 1 views
1

私はフォトギャラリーのように動作するアプリを持っており、ユーザーが画像を削除する機能を実装しています。ここにはセットアップがあります:私は9 UIImageViews、imageView、imageView2などがあります。私も "編集"ボタンとtapGestureアクションメソッドを持っています。 Tap Gesture RecognizerをIBの私の視点にドラッグし、それをUIImageViewsのそれぞれに添付しました。また、UIImageViewのそれぞれにtapGestureアクションメソッドを添付しました。理想的には、「編集」ボタンが押されたときにのみメソッドがアクティブになるようにします。ユーザーが「編集」をタップして削除したい画像をタップすると、UIAlertViewが表示され、削除したいと思っているかどうかが尋ねられます。ここで私が使用しているコードは次のとおりです。iOS:TapGestureRecognizer問題

- (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の対象には見られません私はプログラミングに非常に新しいです、と私は驚きだ((UIImageView *)[self.view]).image =nil;

この行の「UIImageView *view = [self.UIImageView];

そして、このライン上に 『期待される識別子』 PhotoViewControllerを入力私はこれまでこれを作っていました。だから、私はエラーをなくすために私のコードをどのように編集する必要があるのか​​を理解しようとしているだけで、9つの画像ビューの1つがタップされるといつでも使用できます。編集ボタンが最初に押されます。以前はタグを使用していましたが、うまくいきましたが、NSData経由で画像を保存するので、タグを使用できなくなりました。どんな助けも大変ありがとう!ありがとう!

答えて

2

まず、画像ビューにタップジェスチャーを添付したくありません。また、9つ以上の画像を持っている場合は、スクロール表示が必要な場合や、別々にスクロールする場合があります。まず、そのジェスチャ認識装置とすべての接続を削除します。

次に、ギャラリーキャンバスとして使用するビューのタイプを決定します。シンプルなビュー、ScrollView、または何でも...現時点では問題ではありませんが、ただ機能させるだけです。そのビューをCtrlキーを押しながらインターフェイス定義にドラッグすると、ビューのIBOutletがドロップされます(コードで参照できるようになります)。

あなたは先ほど紹介したビューにImageViewsを配置します。

ジェスチャ認識機能の内部フラグを設定することもできますが、必要に応じていつでも有効/無効を切り替えることができます。したがって、あなたはそれをかなり簡単にアクティブ/非アクティブにすることができます。

あなたがしたいことは、コントローラに1つのタップジェスチャ認識機能をドロップし、それをコントローラの実装セクションに接続するだけです。これは、認識装置を処理するためのスタブを生成します。コントローラーのタップを「一般的に」解釈し、タップが表示されるたびにコードを呼び出します。

いくつかのより多くのコード...

は、スクロールビューで「新しい」イメージのためのフレームを作成します。

- (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]; 

だから、あなたはちょうどあなたが持っている唯一のものを、各フレームを作成してビューに追加し、 doはスクロールビューがジェスチャーを通過することを許可しないため、ユーザーの操作を有効にします。

OK ...あなたが投稿したコードを見る...あなたが何が間違っていたかを言わなかったので...言いにくいです...以下はあなたのコードです...私のコメントは、よく、コメント...

- (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]; 
     } 
    } 
} 
+0

ああ大丈夫です、ありがとう!そこで、私がやったことをすべて削除した後、新しいタップジェスチャ認識機能をコントロールにドラッグしました(IBのサイドバーに表示されてしまいました)。次に、タップジェスチャ認識機能を制御アイコンにドラッグしてコントロールアイコンをドラッグし、表示されたアウトレットを「代理人」にしました。私もそれに接続しました。正しい動きをしましたか?信じられないほどの初心者の質問に申し訳ありません、そして私はあなたの助けを大いに感謝します。 – John

+1

いいえ、ボタンからコードにCtrlキーを押したままにしてもよろしいですか?入力した関数スケルトンが生成され、ボタンが押されるとその関数が呼び出されます。タップジェスチャーで同じことをしてください。 Ctrlキーを押しながらコードにドラッグすると、ユーザーが画面をタップすると呼び出される関数が呼び出されます。それが、コードが適切なUIImageViewを見つけるための場所です。 –

+0

私は実際には、左側のサイドバーのタップジェスチャー認識アイコンからすぐ上のコントロールアイコンまでドラッグしてコントロールしました。申し訳ありませんが、私はタップジェスチャ認識ツールアイコンから実際のコードまでドラッグを制御するにはどうすればよいですか?私はビューコントローラの.mファイルにドラッグを制御する必要がありますか? – John

0

私が頭の上から外して考えるのが最も簡単なことは、ジェスチャーをデフォルトでは無効にしてから、編集ボタンを押すとジェスチャーを有効にすることです。このようにして、ピクチャは「編集」モードにある場合にのみタップジェスチャ認識器に応答します。

+0

素晴らしい、おかげで多くは、私は今その権利になります。また、あなたは上記のエラーコードを取り除く方法について考えていますか?私はすべてが捨てられたと思っていました。私はそれがなぜないのか分かりません。初心者の質問に申し訳ありません、私はここに行くように勉強しています。 – John

1

個人的に、私の小さなフォトギャラリーでは、私が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を追加します。私はこれを即座に編集しようとしましたので、事前にお詫びしておきますが、プロセスでエラーが発生した場合はお詫びしておきます。別の(私は100枚近くあり、メインキューにこれを行うことは遅すぎるので、私が行う。)GCDキューとにかく

、あなたは、あなたのUIAlertViewのあなたの表示を行うには、あなたのbuttonClickedメソッドを作成することができます。

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

は最後に、あなたはあなたのUIAlertView上の2つのボタンがありますが、ユーザーがクリックしたものを、ボタンを確認していないように見えます。あなたのビューコントローラは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 
}