Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在iOS中保存图像_Objective C_Ios_Plist_Nsuserdefaults - Fatal编程技术网

Objective c 在iOS中保存图像

Objective c 在iOS中保存图像,objective-c,ios,plist,nsuserdefaults,Objective C,Ios,Plist,Nsuserdefaults,我有一个像照片库一样运行的应用程序。我通过在每个UIImageView上放置一个不可见的按钮,并在用户点击按钮时调用removeObject,实现了用户删除照片的功能。这段代码工作得很好,但它依赖于标记。我需要标记interface builder中的每个UIImageView/UIButton,以使其正常工作。所以,我现在正试图以一种我的标记仍然有效的方式保存图像,这排除了使用NSData 所以我完全不知道现在该做什么。我对编程非常、非常陌生,我甚至走了这么远都感到震惊。非常感谢您对如何编辑我

我有一个像照片库一样运行的应用程序。我通过在每个UIImageView上放置一个不可见的按钮,并在用户点击按钮时调用removeObject,实现了用户删除照片的功能。这段代码工作得很好,但它依赖于标记。我需要标记interface builder中的每个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

前面的评论是准确的;请考虑一下你将如何扩大规模

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

UIImage支持NSCoding,因此您可以使用它。阅读如何使用它,因为你最终会需要它。或者,如果您知道您总是希望使用PNG或JPEG格式,则有函数
UIImagePNGRepression(UIImage*image)
UIImageJPEG表示法(UIImage*image,CGFloat压缩质量)
。要将NSData对象转换回UIImage,请使用
[UIImage imageWithData:NSData*]
以下是您在ApplicationIdentinterBackground中可以使用的内容:

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]];
这将解决你当前的问题,但请不要认为这是永久的解决办法。考虑:

  • 将图像存储在文件或核心数据中,因为NSUserDefaults不是 应该有大量的内容
  • 使用UITableView显示图像,这样您就可以 任意数字,而不是三的硬编码
  • 如果UITableView没有所需的布局,请创建自定义视图 UIView子类,显示一组图像并适当响应点击
  • 确保您的应用程序能够检测到所有可能的方式 暂停或关闭。你可能并不总是能得到最好的结果 ApplicationIdentinterBackground通知,否则您可能没有时间 在数据发生后保存所有数据。如果你有多个 UIViewController,可以在不使用应用程序的情况下卸载此控制器 它自己接收通知

  • 看起来您使用标记只是为了识别正在选择的图像视图。在每个图像的顶部都有一个“不可见”按钮?是这样吗?我假设是这样,你可以处理一个点击,选择通过按钮显示的图像

    有很多方法可以做到这一点,但一个简单的解决方案是只识别点击,并“找到”该点击下的图像视图。从情节提要中将UITapgestureRecognitor放到控制器上。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.
          }
        }
      }
    

    如果您确实必须使用当前的设计,请在nsuserdefaults上保存图像的引用/路径,而不是图像本身。创建一个包含标记号的文件名约定,您应该能够找到保存的图像文件。@Rog听起来不错,谢谢。我该怎么做?很抱歉,对于这个新手问题,我还是个新手。我已将您的代码复制并粘贴到我的AppDienterBackground和viewDidLoad方法中,但由于某些原因,图像仍然无法保存。在将dataArray添加到NSUserDefaults之前,您能否
    NSLog
    将其内容保存,在您检索到它之后,又会发生什么呢?ApplicationIdentinterBackground中的NSLog呢?另外,如果您可以确认数据似乎正在写入NSUserDefaults,请立即再次尝试读取相同的密钥。非常感谢,这是一个好主意。我对编程还是很陌生,所以在实现这一点时遇到了一些问题。关于实现这一点,我提出了一个新问题:非常感谢您的任何意见。再次感谢!