1

フォトギャラリーのように動作するアプリがあります。各UIImageViewの上に非表示のボタンを配置し、ボタンをタップしたときにremoveObjectを呼び出すことで、ユーザーが写真を削除する機能を実装しています。このコードはうまく機能していますが、タグに依存しています。これを機能させるには、InterfaceBuilderのすべてのUIImageView/UIButtonにタグを付ける必要があります。そのため、NSDataの使用を除いて、タグが引き続き機能するように画像を保存しようとしています。

だから私は今何をすべきか完全に迷っています。私はプログラミングに非常に慣れていないので、ここまでやってきたことにショックを受けています。この機能を実現するためにコードを編集する方法や方法に関するヘルプやアドバイスは大歓迎です。ありがとうございます。

これが参考のために私のファイル全体です:

- (IBAction)grabImage {
    self.imgPicker = [[UIImagePickerController alloc] init];
    self.imgPicker.delegate = self;
    self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        _popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
        [_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    } 

    else {
        [self presentModalViewController:imgPicker animated:YES];
    }
    [self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
    if (imageView.image == nil) {
        imageView.image = img;

        [self.array addObject:imageView.image];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;

    }

    if (imageView2.image == nil) {
        imageView2.image = img;
        NSLog(@"The image is a %@", imageView);
        [self.array addObject:imageView2.image];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView3.image == nil) {
        imageView3.image = img;

        [self.array addObject:imageView3.image];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView4.image == nil) {
        imageView4.image = img;

        [self.array addObject:imageView4.image];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }
    if (imageView5.image == nil) {
        imageView5.image = img;

        [self.array addObject:imageView5.image];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

- (void)applicationDidEnterBackground:(UIApplication*)application {
    NSLog(@"Image on didenterbackground: %@", imageView);

    [self.array addObject:imageView.image];
    [self.array addObject:imageView2.image];
    [self.array addObject:imageView3.image];
    [self.array addObject:imageView4.image];
    [self.array addObject:imageView5.image];

    [self.user setObject:self.array forKey:@"images"];
    [user synchronize];

}

- (void)viewDidLoad
{
    self.user = [NSUserDefaults standardUserDefaults];
    NSLog(@"It is %@", self.user);
    self.array = [[self.user objectForKey:@"images"]mutableCopy];
    imageView.image = [[self.array objectAtIndex:0] copy];
    imageView2.image = [[self.array objectAtIndex:1] copy];
    imageView3.image = [[self.array objectAtIndex:2] copy];
    imageView4.image = [[self.array objectAtIndex:3] copy];
    imageView5.image = [[self.array objectAtIndex:4] copy];



    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidEnterBackground:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:app];

    [super viewDidLoad];

}


// This is when the user taps on the image to delete it.
- (IBAction)deleteButtonPressed:(id)sender {
    NSLog(@"Sender is %@", sender);
    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];

    int imageIndex = ((UIButton *)sender).tag;
    deleteAlertView.tag = imageIndex;
}

- (UIImageView *)viewForTag:(NSInteger)tag {
    UIImageView *found = nil;
    for (UIImageView *view in self.array) {
        if (tag == view.tag) {
            found = view;
            break;
        }
    }
    return found;
}

- (void)alertView: (UIAlertView *) alertView 
clickedButtonAtIndex: (NSInteger) buttonIndex
{


    if (buttonIndex != [alertView cancelButtonIndex]) {
        NSLog(@"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
        NSLog(@"The tag is %i", alertView.tag);

        UIImageView *view = [self viewForTag:alertView.tag];
        if (view) {
            [self.array removeObject:view];
        }

        NSLog(@"After deleting item, array count  = %d", [array count]);
        NSLog(@"Returned view is :%@, in view: %@", [self.view viewWithTag:alertView.tag], self.view);
        ((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
    }

    [self.user setObject:self.array forKey:@"images"];
}

@end
4

2 に答える 2

1

前のコメントは正確です。これをどのようにスケールアップするかを考えてください。

そうは言っても、何らかの方法で画像を保存およびロードする必要があります。これは、常にUIImageオブジェクトをNSDataに変換することを意味します。これは、NSUserDefaults、ファイル、またはCoreDataに保存するかどうかに関係なく適用されます。

UIImageはNSCodingをサポートしているので、それを使用できます。最終的に必要になるので、使い方を読んでください。または、常にPNGまたはJPEG形式を使用することがわかっている場合は、関数UIImagePNGRepresentation(UIImage *image)とがありUIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality)ます。NSDataオブジェクトをUIImageに戻すには、次を使用します。applicationDidEnterBackgroundで使用[UIImage imageWithData:NSData*]できるものは次のとおりです。

NSMutableArray *dataArray = [NSMutableArray array];
[dataArray addObject:UIImagePNGRepresentation(imageView.image)];
[dataArray addObject:UIImagePNGRepresentation(imageView2.image)];
[dataArray addObject:UIImagePNGRepresentation(imageView3.image)];
[self.user setObject:dataArray forKey:@"images"];
[self.user synchronize];

次に、viewDidLoad中にこれらを取得するには:

[self.array removeAllObjects];
NSArray *dataArray = [self.user objectForKey:@"images"];
for (NSData *imageData in dataArray)
    [self.array addObject:[UIImage imageWithData:imageData]];

これで当面の問題は解決しますが、恒久的な解決策とは考えないでください。検討:

  1. NSUserDefaultsには大量のコンテンツが含まれていないと想定されているため、画像をファイルまたはCoreDataに保存します。
  2. UITableViewを使用して画像を表示します。これにより、3つをハードコーディングする代わりに、任意の数を指定できます。
  3. UITableViewに必要なレイアウトがない場合は、画像の配列を表示し、タップに適切に応答するカスタムUIViewサブクラスを作成します。
  4. アプリケーションが一時停止またはシャットダウンされる可能性のあるすべての方法を検出できることを確認してください。ApplicationDidEnterBackground通知を常に受け​​取るとは限らない場合や、発生後にすべてのデータを保存する時間がない場合があります。複数のUIViewControllerがある場合、アプリケーション自体が通知を受信せずに、これをアンロードすることができます。
于 2012-04-07T01:17:03.250 に答える
1

選択されている画像ビューを識別できるように、タグを使用しているようです。各画像の上に「非表示」ボタンがありますか?そうですか?ボタンを通して表示されている画像を選択するタップを処理できるようにするためだと思いますか?

それを行う方法はたくさんありますが、簡単な解決策は、タップを認識し、そのタップの下にある画像ビューを「見つける」ことです。ストーリーボード内からコントローラーにUITapGestureRecognizerをドロップします。Ctrlキーを押しながらコントローラーのコードにドラッグすると、アクションメソッドが作成されます。このように記入してください...

  - (IBAction)tapGesture:(UITapGestureRecognizer*)gesture
  {
    CGPoint tapLocation = [gesture locationInView: self.galleryView];
    for (UIImageView *imageView in self.galleryView.subviews) {
      if (CGRectContainsPoint(imageView.frame, tapLocation)) {
        // This is the imageView that was tapped on!
        // Do whatever you want with it now that you found it.
      }
    }
  }
于 2012-04-10T20:28:31.667 に答える