简体   繁体   中英

Restore UIView from NSData

I want to store a UIView in NSData and later on recover the UIView from the stored NSData. As far as I can see in debugger, it works, but I can't see the UIView after restoring. This is my code:

- (IBAction)selStore:(id)sender {
    dImageView = [NSKeyedArchiver archivedDataWithRootObject:ivDemo];
}

- (IBAction)selDelete:(id)sender {
    NSArray *viewsToRemove = [ivDemo subviews];
    for (UIView *v in viewsToRemove) {
        [v removeFromSuperview];
    }
}

- (IBAction)selRestore:(id)sender {
    ivDemo = [NSKeyedUnarchiver unarchiveObjectWithData:dImageView];
    [ivDemo setNeedsDisplay];
}

Here the results from the debugger after storing the UIView in NSData dImageView 在此输入图像描述

In _subviewCache are the two UIImageView I added to the UIView.

Here the results from the debugger after deleting the subviews in UIView: 在此输入图像描述

No _subviewCache are there

Finally I restore the UIView from NSData 在此输入图像描述

the _subviewCache shows the two UIImageViews

BUT, the UIView is not refreshed on iPad screen. Any idea what I am missing?

I was really curious to see if this was possible (although I can't think of a reason when I'd use it).

I explored this in Swift, but there should be no difference between Objective-C and Swift in this case.

I found that I could archive/unarchive a single view fine, but as soon as I tried to archive a view with subviews that it acted unexpectedly.

The best I could do was to archive an array of views, but again they could only be siblings rather than a nested view hierarchy.

You'd probably have more luck to create some data model that represented your views, archive the model, and then re-create the views using your model.

import UIKit

class ViewController: UIViewController {

    var archiver:NSData?

    @IBOutlet weak var containerView: UIView!

    @IBAction func toggle(sender: UIButton) {

        if let data = self.archiver {
            if let views = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [UIView] {

                for view in views {
                    self.containerView.addSubview(view)
                }

                self.archiver = nil
            }
        }
        else {
            let views = self.containerView.subviews

            for view in views {
                view.removeFromSuperview()
            }

            self.archiver = NSKeyedArchiver.archivedDataWithRootObject(views)
        }
    }
}

you can use encodeWithCoder: to get a serialized object, and initWithCoder: to reconstruct a imageview or any view for restoration. Please go through this doc: Serializations Programming Guide for Cocoa .

eg:

- (void)encodeWithCoder:(NSCoder *)coder {

    if ([coder isKindOfClass:[NSKeyedArchiver class]]) {
        [coder encodeObject:self.user.firstName forKey:kFirstName];
        [coder encodeObject:self.user.dateOfBirth forKey:kDateOfBirth];
        [coder encodeFloat:self.user.imageView forKey:kUserImageView];
    }
    else {
        [NSException raise:NSInvalidArchiveOperationException format:@"Only supports NSKeyedArchiver coders"];
    }
}

- (void)decodeWithCoder:(NSDecoder *)decoder {



if ([decoder isKindOfClass:[NSKeyedUnarchiver class]]) {
        NSString *userName = [decoder decodeObjectForKey:kFirstName];
        NSDate *dateOfBirth = [decoder decodeObjectForKey:kDateOfBirth];
        UIImageView *userImageView = [decoder decodeObjectForKey:kUserImageView];
    }
    else {
        [NSException raise:NSInvalidArchiveOperationException format:@"Only supports NSKeyedUnarchiver decoders"];
    }
    }

- (NSData *)dataForObject:(User *)userProfile {
  NSMutableData *archivingData = [NSMutableData data];
  NSKeyedArchiver  *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archivingData];
  [archiver encodeObject:userProfile forKey:@"userProfile"];
  [archiver finishEncoding];
  archiver = nil;

  return (id)data;
}

- (User *)userProfileForData:(NSData *)data {
  NSKeyedUnarchiver  *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

  User *userProfile = [unarchiver decodeObjectForKey:@"userProfile"];
  [unarchiver finishDecoding];
  unarchiver = nil;

  return view;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM