You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何保存相机拍摄的图片并在另一个ViewController中展示?

Solution: Save Images & Display in Collection View

Hey there! Let's get your photo saving and collection view display working properly. I'll break this down into clear, actionable steps with code examples tailored to your existing implementation.


Step 1: Add Image Persistence Logic

First, we need to save the selected/captured images to your app's Documents directory (so they persist between app launches) and keep track of their filenames. Add these methods to your ViewController.m:

// Helper method to save image to Documents directory
- (BOOL)saveImageToDocuments:(UIImage *)image withFileName:(NSString *)fileName {
    NSData *imageData = UIImageJPEGRepresentation(image, 0.8); // 0.8 balances quality and file size
    if (!imageData) return NO;
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths firstObject];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
    
    return [imageData writeToFile:filePath atomically:YES];
}

// Helper method to get saved images filenames from UserDefaults
- (NSMutableArray *)savedImageFilenames {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *filenames = [[defaults objectForKey:@"SavedImageFilenames"] mutableCopy];
    if (!filenames) filenames = [NSMutableArray array];
    return filenames;
}

Now update your imagePickerController:didFinishPickingMediaWithInfo: method to save the image and update the filename list:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
    self.imageView.image = chosenImage;
    
    // Generate a unique filename using timestamp to avoid duplicates
    NSString *fileName = [NSString stringWithFormat:@"Photo_%f.jpg", [[NSDate date] timeIntervalSince1970]];
    
    // Save the image and update the saved filenames list
    if ([self saveImageToDocuments:chosenImage withFileName:fileName]) {
        NSMutableArray *savedFilenames = [self savedImageFilenames];
        [savedFilenames addObject:fileName];
        [[NSUserDefaults standardUserDefaults] setObject:savedFilenames forKey:@"SavedImageFilenames"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    
    [picker dismissViewControllerAnimated:YES completion:NULL];
}

Step 2: Create the Photo Collection View Controller

Create a new UIViewController subclass named PhotoCollectionViewController (check "Also create XIB file" or use Storyboard based on your setup).

Configure the Collection View

  1. Add a UICollectionView to the view controller, set constraints to fill the entire view.
  2. Set the collection view's dataSource and delegate to the view controller.
  3. Create a UICollectionViewCell subclass (e.g., PhotoCell) with a UIImageView inside, set constraints for the image view to fill the cell.

Code for PhotoCollectionViewController.m

#import "PhotoCollectionViewController.h"
#import "PhotoCell.h"

@interface PhotoCollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) NSMutableArray *imageFilenames;
@property (nonatomic, strong) NSString *documentsDirectory;
@end

@implementation PhotoCollectionViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Get path to Documents directory
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    self.documentsDirectory = [paths firstObject];
    
    // Load saved image filenames from UserDefaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    self.imageFilenames = [[defaults objectForKey:@"SavedImageFilenames"] mutableCopy];
    if (!self.imageFilenames) self.imageFilenames = [NSMutableArray array];
    
    // Register the cell class (skip if using Storyboard/XIB with identifier)
    [self.collectionView registerClass:[PhotoCell class] forCellWithReuseIdentifier:@"PhotoCell"];
}

#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.imageFilenames.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
    
    // Load image from Documents directory
    NSString *fileName = self.imageFilenames[indexPath.row];
    NSString *filePath = [self.documentsDirectory stringByAppendingPathComponent:fileName];
    cell.imageView.image = [UIImage imageWithContentsOfFile:filePath];
    
    return cell;
}

#pragma mark - UICollectionView DelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    // Show 3 columns with small spacing
    CGFloat width = (collectionView.bounds.size.width - 20) / 3;
    return CGSizeMake(width, width);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(10, 10, 10, 10);
}

@end

Code for PhotoCell.h

#import <UIKit/UIKit.h>

@interface PhotoCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@end

Code for PhotoCell.m

#import "PhotoCell.h"

@implementation PhotoCell

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        self.imageView.contentMode = UIViewContentModeScaleAspectFill;
        self.imageView.clipsToBounds = YES;
        [self.contentView addSubview:self.imageView];
    }
    return self;
}

@end

Step 3: Navigate to the Collection View Controller

Add a button (or any trigger) in your original ViewController to push/present the PhotoCollectionViewController. For example, add this IBAction:

- (IBAction)showPhotoCollection:(UIButton *)sender {
    PhotoCollectionViewController *collectionVC = [[PhotoCollectionViewController alloc] init];
    [self.navigationController pushViewController:collectionVC animated:YES];
    // Use this instead if not using a navigation controller:
    // [self presentViewController:collectionVC animated:YES completion:nil];
}

Important Notes

  • Permissions: Don't forget to add required privacy permissions to your Info.plist:
    • NSCameraUsageDescription (explain why your app needs camera access)
    • NSPhotoLibraryUsageDescription (explain why your app needs photo library access)
  • Image Quality: Adjust the compression value in UIImageJPEGRepresentation (0.0 to 1.0) based on your quality/storage needs.
  • Scalability: For apps with many images, consider using Core Data instead of UserDefaults to store filenames for better performance and management.

内容的提问来源于stack exchange,提问作者Dhanush kumar Sivaji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:02:29