0

私はプログラミングに非常に慣れていないので、すぐにプロジェクトに飛び込みました(これは賢明なことではないことはわかっていますが、学習しながら学んでいます)。私が書いているアプリには、ユーザーのカメラロールからの画像を表示する10個のUIImageViewがあります。私が使用しているコードでは、各UIImageViewにタグが必要です。現在、NSDataを使用して配列イメージを保存しています。これはうまく機能しますが、NSDataはタグの使用をサポートしていないため、このメソッドを使用できなくなりました。また、画像をplistに保存できないため、NSUserDefaultsを使用できません。これを実行しようとしている方法は次のとおりです(NSDataメソッドを使用します。これは機能しますが、タグが機能するように編集する必要があります)。

これは私の現在のコードです:

- (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;
    }
    ...


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

    [self.array addObject:imageView.image];
    [self.array addObject:imageView2.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];    

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

    [super viewDidLoad];

}

タグを使用しながら画像を保存できるようにこのコードを編集する方法についてのヘルプや提案はありがたいです、ありがとう!

編集:これが私の更新されたコードです:

       -(IBAction)saveButtonPressed:(id)sender {
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];

    for (UIImageView *imageView in self.array) {

        NSInteger tag = self.imageView.tag;
        UIImage *image = self.imageView.image;
        NSString *imageName = [NSString stringWithFormat:@"Image%i.png",tag];

        NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
        [UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
    }
NSLog(@"Saved Button Pressed");
}



- (void)applicationDidEnterBackground:(UIApplication*)application {

}


-(void)viewDidLoad {

    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];

    NSArray *docFiles = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:docsDir error:NULL];

    for (NSString *fileName in docFiles) {

        if ([fileName hasSuffix:@".png"]) {
            NSString *fullPath = [docsDir stringByAppendingPathComponent:fileName];
            UIImage *loadedImage = [UIImage imageWithContentsOfFile:fullPath];

            if (!imageView.image) {
                imageView.image = loadedImage;
            } else {
                imageView2.image = loadedImage;
            }
        }
    }
}
4

3 に答える 3

4

「高速列挙」を使用して配列のオブジェクトを解析し、各オブジェクトを順番にディスクに書き込む必要があります。まず、UIImageViewのUIImageプロパティではなく、UIImageViewオブジェクトを配列に追加して、タグを復元できるようにする必要があります。だから書く代わりに

[self.array addObject:imageView.image];

そうなる

[self.array addObject:imageView];

私のコードに従ってください。役立つように、各行にコメントを挿入しました。

-(void)applicationDidEnterBackground:(UIApplication *)application {
    //Obtain the documents directory
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainmask,YES) objectAtIndex:0];
    //begin fast enumeration
    //this is special to ObjC: it will iterate over any array one object at a time
    //it's easier than using for (i=0;i<array.count;i++)
    for (UIImageView *imageView in self.array) {
        //get the imageView's tag to append to the filename
        NSInteger tag = imageView.tag;
        //get the image from the imageView;
        UIImage *image = imageView.image;
        //create a filename, in this case "ImageTAGNUM.png"
        NSString *imageName = [NSString stringWithFormat:@"Image%i.png",tag];
        //concatenate the docsDirectory and the filename
        NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
        [UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
    }
}

ディスクから画像をロードするには、viewDidLoadメソッドを確認する必要があります

-(void)viewDidLoad {
    //get the contents of the docs directory
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainmask,YES) objectAtIndex:0];
    //Get the list of files from the file manager
    NSArray *docFiles = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:docsDir error:NULL]);
    //use fast enumeration to iterate the list of files searching for .png extensions and load those
    for (NSString *fileName in docFiles) {
        //check to see if the file is a .png file
        if ([fileName hasSuffix:@".png"]) {
            NSString *fullPath = [docsDir stringByAppendingPathComponent:fileName];
            UIImage *loadedImage = [UIImage imageWithContentsOfFile:fullPath];
            //you'll have to sort out how to put these images in their proper place
            if (!imageView1.image) {
                imageView1.image = loadedImage;
            } else {
                imageView2.image = loadedImage;
            }
        }
    }
}

お役に立てれば

注意する必要があることの1つは、アプリがバックグラウンドに入ると、停止する前にその動作をクリーンアップするのに約5秒かかるということです。UIPNGRepresentation()関数はかなりの時間がかかり、瞬時ではありません。これに注意する必要があります。このコードの一部を他の場所で記述し、アプリのバックグラウンド処理よりも早く実行する方がおそらく良いでしょう。FWIW

于 2012-04-13T20:25:20.467 に答える
1

まず、forループにまだ問題があります。

for (UIImageView *imageView in self.array) {
    NSInteger tag = self.imageView.tag;
    UIImage *image = self.imageView.image;
    // ...
}

他の変更を行う前に、その理由を理解する必要があります。 imageViewforループ制御変数であり、ループの反復ごとに変化します。 self.imageView別のものです。これは、viewControllerにアタッチされた10個のimageViewの最初のものです。このループが繰り返されるたびに、最初のimageViewが表示され、最初の画像のみが表示されます。

保存が機能しない理由については、他の場所のアレイが機能していないことが原因である可能性があります。いくつかのロギングを追加して、配列に何かがあり、期待する数の要素が含まれていることを確認します。

-(IBAction)saveButtonPressed:(id)sender {
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];

    // Log to make sure the views expected have previously been stored.
    // If the array is empty, or shorter than expected, the problem is elsewhere.
    NSLog(@"Image view array before saving = %@", self.array);

    for (UIImageView *imageViewToSave in self.array) {

        NSInteger tag = imageViewToSave.tag;
        UIImage *image = imageViewToSave.image;
        NSString *imageName = [NSString stringWithFormat:@"Image%i.png",tag];

        NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];

        // Log the image and path being saved.  If either of these are nil, nothing will be written.
        NSLog(@"Saving %@ to %@", image, imagePath);

        [UIImagePNGRepresentation(image) writeToFile:imagePath atomically:NO];
    }
    NSLog(@"Save Button Pressed");
}
于 2012-04-14T03:31:20.263 に答える
1

[NSbundleMainbundel]を使用してその画像を保存できます。

パスを取得するには

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

 NSString *documentsDirectory = [paths objectAtIndex:0];
于 2012-04-11T03:44:18.423 に答える