2012-04-07 174 views
1

我有一个应用程序,其行为像一个照片库。我正在实施用户删除照片的功能,方法是在每个UIImageView上放置一个不可见按钮,并在点击按钮时调用removeObject。此代码运行良好,但依赖于标签。我需要在界面构建器中为每个UIImageView/UIButton添加标签才能使其工作。所以,我现在试图以我的标签仍然可以工作的方式保存图像,这排除了使用NSData。在iOS中保存图像

所以我完全失去了现在要做的事情。我对编程非常非常陌生,对于我甚至做到这一点感到震惊。有关如何编辑我的代码以进行此项工作的任何帮助或建议,非常感谢,谢谢!

这里是我的整个文件仅供参考:

- (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 
+1

如果你真的必须使用这个设计,你现在已经在nsuserdefaults上保存一个图像的参考/路径,而不是图像本身。创建一个包含标签编号的文件名约定,您应该能够找到保存的图像文件。 – Rog 2012-04-07 00:49:18

+0

@Rog这听起来像个好主意,谢谢。我会怎么做?对于新手问题抱歉,我对此仍然很陌生。 – John 2012-04-07 00:59:25

回答

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. 
     } 
    } 
    } 
+0

非常感谢,这是一个好主意。我对编程还很陌生,所以我遇到了一些问题。我创建了一个关于实现这个问题的新问题: http://stackoverflow.com/questions/10097855/ios-tapgesturerecognizer-issues 任何输入是非常赞赏。再次感谢! – John 2012-04-10 23:23:08

1

以前的评论是准确的;请考虑你将如何扩大规模。

也就是说,您需要以某种方式存储和加载图像,这将始终意味着将您的UIImage对象转换为NSData。无论您将它们存储在NSUserDefaults,文件还是核心数据中,这都适用。

UIImage支持NSCoding,所以你可以使用它。阅读如何使用它,因为最终你会需要它。或者,如果您知道您始终想要使用PNG或JPEG格式,则有功能UIImagePNGRepresentation(UIImage *image)UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality)。要转换NSData的对象返回的UIImage,使用[UIImage imageWithData:NSData*]这里是你可以在applicationDidEnterBackground什么:

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不是 应该有大量的内容。
  2. 使用UITableView来显示图像,所以你可以有一个 任意数字,而不是三个硬编码。
  3. 如果UITableView没有您需要的布局,请创建一个自定义的 UIView子类,用于显示图像数组并适当地响应水龙头。
  4. 请确保您的应用程序可以检测到它可能被挂起或关闭的所有方式 。您可能并不总是获得 ApplicationDidEnterBackground通知,或者您可能没有时间 在发生数据后保存所有数据。如果您有多个UIViewControllers,则可能会卸载此UIViewControllers,而应用程序本身不会接收通知。
+0

我将你的代码复制并粘贴到我的appDidEnterBackground和viewDidLoad方法中,但由于某些原因,图像仍然无法保存。 – John 2012-04-09 03:46:09

+0

在将NSArray添加到NSUserDefaults之前,您可以“NSLog”dataArray的内容,并在检索它之后再次进行检查? – Dondragmer 2012-04-09 04:03:15

+0

在applicationDidEnterBackground中的NSLog呢?此外,如果您可以确认数据似乎正在写入NSUserDefaults,请立即再次读取相同的密钥。 – Dondragmer 2012-04-09 04:19:34