如何在切换ViewControllers时保留UITableView内容

时间:2011-11-22 03:07:42

标签: iphone uitableview uiviewcontroller nsmutablearray imageview

我在这里和其他网站上查看了很多代码示例,但是我找不到与这种特殊情况相关的示例,所以我想我会尝试询问。

我的应用程序正在使用启用了自动引用计数(ARC)的实用程序应用程序模板(主视图和翻转视图)。

在侧面视图中,我有一个空的UITableView,其导航栏带有“完成”按钮,可以返回主视图和“添加”按钮。单击“添加”按钮将创建一个空行并激活UIImagePicker。从UIImagePicker中选择照片后,该照片将传递到新单元格的imageView。

我的问题是,在向表格中添加新行后,当我切换到主视图然后返回到翻转视图时,表格再次为空。

我认为这与我将图像写入NSMutableArray的方式有关。

如果有人知道如何在切换视图时保持UITableView不被擦除,那就太棒了。

提前致谢,
斯蒂芬

AppDelegate.h

#import <UIKit/UIKit.h>

@class MainViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) MainViewController *mainViewController;

@end


AppDelegate.m

#import "AppDelegate.h"

#import "MainViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize mainViewController = _mainViewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.mainViewController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
    self.window.rootViewController = self.mainViewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

@end


MainViewController.h

#import "FlipsideViewController.h"

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

- (IBAction)showInfo:(id)sender;

@end


MainViewController.m

#import "MainViewController.h"

@implementation MainViewController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

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

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

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

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

#pragma mark - Flipside View

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)showInfo:(id)sender
{    
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideViewController" bundle:nil];
    controller.delegate = self;
    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];
}

@end

FlipsideViewController.h

#import <UIKit/UIKit.h>

@class FlipsideViewController;

@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
@end

@interface FlipsideViewController : UIViewController <UIActionSheetDelegate, UIAlertViewDelegate, UIImagePickerControllerDelegate,UINavigationControllerDelegate>
{
NSMutableArray *dataArray;
IBOutlet UITableView *tableView;
IBOutlet UIBarButtonItem *addPhotoButton;
UITableViewCell *addedCell;
UIImage *image;
UIImagePickerController *imagePicker;
}

@property (nonatomic, strong) NSMutableArray *dataArray;
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) IBOutlet UIBarButtonItem *addPhotoButton;
@property (nonatomic, strong) UITableViewCell *addedCell;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImagePickerController *imagePicker;

@property (weak, nonatomic) IBOutlet id <FlipsideViewControllerDelegate> delegate;

- (IBAction)addPhoto:(id)sender;
- (IBAction)done:(id)sender;
@end


FlipsideViewController.m

#import "FlipsideViewController.h"
#import "MainViewController.h"

@implementation FlipsideViewController

@synthesize delegate = _delegate;
@synthesize dataArray, tableView, addPhotoButton, addedCell, image, imagePicker;

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];

self.dataArray = [[NSMutableArray alloc] init];
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.allowsEditing = NO;    
self.imagePicker.delegate = self;   
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}

#pragma mark - UITableView delegate methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = @"cellID";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.showsReorderControl = YES;
}

return cell;
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

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

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

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

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

#pragma mark - Actions

- (IBAction)addPhoto:(id)sender
{
[self presentModalViewController:self.imagePicker animated:YES];
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
// AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
// appDelegate.pickerImage = img;

image = img;
[self dismissModalViewControllerAnimated:YES];

[self.tableView beginUpdates]; 
[self.dataArray addObject:@""];
NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:(self.dataArray.count - 1) inSection:0]];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:NO];
[self.tableView endUpdates];

addedCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(self.dataArray.count - 1) inSection:0]];
addedCell.imageView.image = image;
[self.tableView reloadData];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
[self.dataArray removeObjectAtIndex:row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
@end

2 个答案:

答案 0 :(得分:0)

您需要将选择信息保存在独立于flipview的某个持久位置。当你回到flipview时,首先检查是否有保存的选择,然后根据它加载你的表。

答案 1 :(得分:0)

你需要问自己一些问题,因为这是一个逻辑问题。

如何在FlipsideViewController中创建MainViewController

您是否每次都创建一个新的,如果是或否是什么原因?

你如何保持数据存活?

可能会发生至少3或4种方式,主要是在MainViewController中。

如果这些问题对您没有帮助,请发布MainViewController代码。


- (IBAction)showInfo:(id)sender  // this is trigger by IB
{    
//This is created each time
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideViewController" bundle:nil];  
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

// HERE the 'controller' get retain by self and you don't have reference to it anymore,
[self presentModalViewController:controller animated:YES]; 

// So when the ModalView is finish your controller will be trash with all it's data
// If you don't hold on to something it will go away, thanks to ARC
}

问题在于对象的生命周期

如果您认为用户将转到您的FlipsideView,您可以创建一次并将其保存在MainView的属性中。 如果没有,您可以在MainView中缓存数组,并在创建后立即将其传递给Flipside。 (在这两种情况下,如果您希望在应用程序启动之间保持持久性,则需要将可变阵列保存到磁盘。如果将其保存到磁盘,它也可能是直接转到磁盘以获取信息的Flipside)

我建议任何新的Apple程序员来学习和理解retainrelease的内存管理。
因为ARC不是魔术,它代表Automatic Reference Counting。如果您了解retainrelease的工作原理,您将更好地了解ARC的工作原理,并能够清楚地看到物体的生命周期。
(实际上,ARC正在进行retainrelease