使用 UIImagePickerController 后无法恢复为原始图像

Can't Revert Back to Original Image After Using UIImagePickerController

我在使用 uiimagepickercontroller 时遇到一个有趣的小问题,想知道是否有人对可能发生的事情有任何见解。用户可以用相机拍照或从照片库中挑选,直到奶牛连续回家多次为止。我的问题在于允许用户恢复到应用程序附带的原始图像。这是流程:

  1. 用户进入显示图像缩略图的表格视图。
  2. 用户导航到显示图像较大视图的详细视图。
  3. 用户可以点击详细视图中的图像以调出自定义警报控制器,其中包含以下选项:a) 使用相机拍照,b) 使用他们图库中的图片,或 c) 恢复到原图。
  4. 用户选择选项 'a' 或选项 'b' 来拍照或使用照片库中的图片。如果他们立即改变了使用这些选择之一的想法并只想返回使用原始图像,则什么也不会发生!他们可以立即拍摄另一张照片或选择另一张图片,但无法立即恢复为原始图像。

当应用程序关闭然后再次打开时,恢复到原始图像确实非常有效。有时,如果您导航到应用程序中的其他视图,然后返回到他们刚刚添加自己图像的详细视图,它会起作用。为何延迟?我已经搜索了两周,但没有发现任何与我的问题相似的问题或任何有帮助的解决方案(比如重新加载图像所在的标题视图)。有什么想法吗?

另外,我已经想出了如何使用文档将图像保存到 iCloud,但无法弄清楚如何检索它们,因此没有相应的代码。那是完全不同的问题。即使没有该代码,同样的事情似乎也会发生。

感谢您抽出宝贵的时间来看这篇文章!

这是一些代码:

    -(void)bookImageTapped:(UIGestureRecognizer *)gesture
{
    URBAlertView *changeImageAlertView = [[URBAlertView alloc] initWithTitle:@"Add A New Book Cover Image" message:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Use Camera", @"Open Gallery", @"Use Original Photo", nil];
    [changeImageAlertView setHandlerBlock:^(NSInteger buttonIndex, URBAlertView *alertView) {

        [self checkPermission];

        if (PHAuthorizationStatusAuthorized)
        {
            if(buttonIndex == 0)
            {
                if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
                {
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
                        pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
                        pickerController.delegate = self;
                        pickerController.allowsEditing = NO;
                        pickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
                        [self presentViewController:pickerController animated:YES completion:nil];
                    }];

                    [alertView hide];
                }
                else
                {
                    NSLog(@"Camera not available");
                    [alertView hide];
                }
            }
            else if (buttonIndex == 1)
            {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
                    pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                    pickerController.delegate = self;
                    pickerController.allowsEditing = NO;
                    pickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
                    [self presentViewController:pickerController animated:YES completion:nil];
                }];
                [alertView hide];
            }
            else if (buttonIndex == 2)
            {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    [self restoreOriginalPhoto];
                }];
                [alertView hide];
            }
            else
            {
                NSLog(@"button 2 cancel");
                [alertView hide];
            }
        }

        }];

        [changeImageAlertView show];

}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info
{
    [picker dismissViewControllerAnimated:YES completion:nil];
    _book.largeBookImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    _book.largeBookImage = [self scaleImage:_book.largeBookImage toSize:CGSizeMake(120, 168)];
    _bookImageView.image = _book.largeBookImage;

    _book.wasNewImageAdded = YES;
    _book.originalImageUsed = NO;

    NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [self saveImage:_book.largeBookImage withFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];

}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
}

-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath
{
    if ([[extension lowercaseString] isEqualToString:@"png"])
    {
        [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];

        //Create a URL to the local file
        NSURL *resourceURL = [NSURL fileURLWithPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]]];
        if (resourceURL)
        {
            CKAsset *asset = [[CKAsset alloc] initWithFileURL:resourceURL];
            //create a record object
            CKRecord *bookCover = [[CKRecord alloc] initWithRecordType:@"Bookcover"];
            //set the record's fields
            bookCover[@"title"] = _book.title;
            bookCover[@"bookImage"] = asset;

            /* TO SAVE A RECORD */
            //get the public database
            CKContainer *appContainer = [CKContainer defaultContainer];
            CKDatabase *publicDatabase = [appContainer publicCloudDatabase];
            [publicDatabase saveRecord:bookCover completionHandler:^(CKRecord *bookCover, NSError *error) {
                if (error)
                {
                    //insert error handling
                    return;
                }
                //insert succesfully saved record code
                NSLog(@"png record saved after using picker!");
            }];
        }
    }
    else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"])
    {
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];

        //Create a URL to the local file
        NSURL *resourceURL = [NSURL fileURLWithPath:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]]];
        if (resourceURL)
        {
            CKAsset *asset = [[CKAsset alloc] initWithFileURL:resourceURL];
            //create a record object
            CKRecord *bookCover = [[CKRecord alloc] initWithRecordType:@"Bookcover"];
            //set the record's fields
            bookCover[@"title"] = _book.title;
            bookCover[@"bookImage"] = asset;

            /* TO SAVE A RECORD */
            //get the public database
            CKContainer *appContainer = [CKContainer defaultContainer];
            CKDatabase *publicDatabase = [appContainer publicCloudDatabase];
            [publicDatabase saveRecord:bookCover completionHandler:^(CKRecord *bookCover, NSError *error) {
                if (error)
                {
                    //insert error handling
                    return;
                }
                //insert succesfully saved record code
                NSLog(@"jpg record saved after using picker!");
            }];
        }
    }
    else
    {
        NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension);
    }
}

- (UIImage *) scaleImage:(UIImage*)image toSize:(CGSize)newSize 
{
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

-(void)restoreOriginalPhoto
{
    NSLog(@"restore photo called");

    _book.originalImageUsed = YES;
    _book.wasNewImageAdded = NO;

    _bookImageView.image = _book.largeBookImage;

    NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [self saveImage:_book.largeBookImage withFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];


}

这是带有图像视图的标题视图:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    _headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 26)];
    _headerView.backgroundColor = [UIColor colorWithRed:8/255.0 green:46/255.0 blue:46/255.0 alpha:0.8];

if (section == 0)
{
    _headerView.backgroundColor = [UIColor whiteColor];

    _bookImageView = [[UIImageView alloc] initWithFrame:CGRectMake((tableView.frame.size.width - 120)/2, 6, 120, 168)];
    _bookImageView.contentMode = UIViewContentModeScaleAspectFit;


    if (_book.wasNewImageAdded)
    {
        NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];
        _bookImageView.image = image;

    }
    else
    {
        _bookImageView.image = _book.largeBookImage;
    }

    if(_book.originalImageUsed)
    {
        NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];
        _bookImageView.image = image;
    }

    UITapGestureRecognizer *bookImageTouched = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(bookImageTapped:)];
    bookImageTouched.numberOfTapsRequired = 1;
    [_bookImageView addGestureRecognizer:bookImageTouched];
    _bookImageView.userInteractionEnabled = YES;

    [_headerView addSubview:_bookImageView];
}

我终于明白了!看来我把 xcode 和我的 属性 名字搞混了。代码最终变得简单多了。

在 didFinishPickingMediaWithInfo 中,我创建了一个 UIImage,然后将其设置为 bookImageView.image。后来,当我希望能够将图像更新回原始图像时,我可以调用 bundle 资产,_book.largeBookImage。瞧!图片能够立即更新。

最相关的代码贴在下面。

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info
{
    [picker dismissViewControllerAnimated:YES completion:nil];

    _chosenImage = [[UIImage alloc] init];
    _chosenImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    _bookImageView.image = _chosenImage;

    _book.wasNewImageAdded = YES;
    _book.originalImageUsed = NO;

    NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [self saveImage:_chosenImage withFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];
}

-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath
{
    if ([[extension lowercaseString] isEqualToString:@"png"])
    {
        [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];

        [self.tableView reloadData];
    }
    else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"])
    {
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];

        [self.tableView reloadData];
    }
    else
    {
        //NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension);
    }
}

-(void)restoreOriginalPhoto
{   
    _book.originalImageUsed = YES;
    _book.wasNewImageAdded = NO;

    _bookImageView.image = _book.largeBookImage;
    _backgroundImage.image = _book.largeBookImage; 
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{   
    if (section == 0)
    {
      _bookImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 120, 168)];
        _bookImageView.contentMode = UIViewContentModeScaleAspectFit;
        _bookImageView.clipsToBounds = YES;
        _bookImageView.layer.cornerRadius = 10.0f;

        if (_book.wasNewImageAdded)
        {
            NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
            UIImage * image = [self loadImageWithFileName:_book.bookImageID ofType:@"jpg" inDirectory:documentsDirectory];
            _bookImageView.image = image;
        }
        else
        {
            _bookImageView.image = _book.largeBookImage;
        }

        if(_book.originalImageUsed)
        {
            _bookImageView.image = _book.largeBookImage;
        }
    }
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if(_book.originalImageUsed)
    {
        _bookImageView.image = _book.largeBookImage;
    }

    [self.tableView reloadData];
    [self.tableView setContentOffset:CGPointZero animated:NO];
}