Remove Image From NSMutableArray - objective-c

So, the app that I'm writing allows the user to upload a photo from their camera roll, and it displays in a UIImageView. I have a "Save" button, that allows the images to be saved when pressed. I also have an "Edit" button, when tapped, it allows the user to tap on the photo and it will be deleted. This is where I'm having issues, the image deletes from the view, but doesn't seem to delete from the array. When I close and relaunch the app, the photo appears again. I'm very new to Objective-C, I'm surprised that I even made it this far, so I'm having issues figuring out how to delete it from the array.
Also, as a side note, if I grab 3 images from the camera roll, delete the middle one, and then press the save button, after closing and relaunching the app it displays only the 2 photos like it should. The issue regarding the image appearing again after relaunch only happens if I press save first, then try and delete them.
This is how I'm deleting them. I have an invisible button over each UIImageView, and when the Edit button is pressed, it unhides them. I've tagged both the buttons and the UIImageViews, and when one of the buttons is pressed, this fires:
- (IBAction)deleteButtonPressed:(id)sender {
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (UIImageView *)viewForTag:(NSInteger)tag {
UIImageView *found = nil;
for (UIImageView *view in self.array) {
if (tag == view.tag) {
found = view;
break;
}
}
return found;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
}
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:#"images"];
}
And just for reference, this is how I'm saving the images:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[self.array addObject:imageView];
[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];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
...
...
}
-(IBAction)saveButtonPressed:(id)sender {
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
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];
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:NO];
}
}
And this is how I'm loading them:
-(void)viewDidLoad {
self.array = [NSMutableArray array];
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 if (!imageView2.image) {
imageView2.image = loadedImage;
}
else if (!imageView3.image) {
imageView3.image = loadedImage;
}
}
}
}
Update: Here is my current code:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (UIImageView *)viewForTag:(NSInteger)tag {
UIImageView *found = nil;
for (UIImageView *view in self.array) {
if (tag == view.tag) {
found = view;
break;
}
}
return found;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"Image%i.png",view.tag]];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:filePath error:NULL];
}
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:#"images"];
}

When you're deleting the image from the array [self.array removeObject:view];, you haven't removed the image itself from the directory.
You may want to do something like this after removing the object from array:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"THE_IMAGE_NAME_HERE.png"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
[fileManager removeItemAtPath:filePath error:&error];
if (error)
NSLog(#"Error: %#",error);

Your array has nothing to do with this. It is overwritten on the next launch anyway. I don't think you are ever deleting your image from the folder, so it is read again on the next launch in your viewDidLoad method.

Related

Save image in UIImagePickerController

I have a small question about how to save a picture in the UIImagePickerController.
I have tried it with the following code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image didFinishPickingMediaWithInfo:(NSDictionary *)info {
if (takePhotoSave == 1) {
takePhotoSave = 0;
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
[picker dismissViewControllerAnimated:YES completion:NULL];
} }
I get no errors, but the image is not saved
Thank you very much
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:NO completion:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo){
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
//save to document directory
NSData *pngData = UIImagePNGRepresentation([self imageWithImage:image scaledToSize:CGSizeMake(image.size.width/5, image.size.height/5)]);
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"image_test.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
}
This is everything you need to save to the photos. If you're looking to save it as an uiimage look below:
if ([NSData dataWithContentsOfFile:[self documentsPathForFileName:#"image_test.png"]]) {
NSData* pngData = [NSData dataWithContentsOfFile:[self documentsPathForFileName:#"image_test.png"]];
UIImage* image = [UIImage imageWithData:pngData];
UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
[imageView setFrame:CGRectMake(0.0, 0.0, imageView.image.size.width, imageView.image.size.height)];
[imageView setCenter:self.view.center];
[self.view addSubview:imageView];
}
The problem here seems to be that you are not setting a completion target.
UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
This works perfectly for me and so should fix your problem.
You can also set a completion target to check that it is being saved correctly:
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:), nil);
// Check if there was an error
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error {
// Unable to save the image
if (error) {
}
// All is well
else {
}
}
Hope this helps

iOS: Image Will Not Delete From Array

I'm working on an app that behaves like a photo gallery, and I'm implementing the option to have the user delete photos from their gallery. To accomplish this, I decided to place an invisible button over each picture. When the user hits an "Edit" button, the hidden delete buttons over each picture become active. I'm using the same IBOutlet over each of the hidden buttons for simplicity, and I've tagged each button appropriately in Interface Builder. When the user taps the button over the picture, an alert view appears asking if they really want to delete it. If they click yes, I call removeObjectAtIndex. Here is the code I'm using:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
The issue here is that when I click "Yes" in the alert view, nothing happens. However, if I tap on the image and click "Yes" a second time, the app crashes, and the debug states:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray removeObjectAtIndex:]: index (0) beyond bounds (0)' So, I'm not sure where to go from here, I'm still very new to programming and everything looks correct to me. Any help is much appreciated, thanks!
Here is how I add them into the array:
////start of saving////
- (void)viewWillAppear:(BOOL)animated
{
self.user = [NSUserDefaults standardUserDefaults];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
while(self.array == nil)
{
[self.user setObject:[NSMutableArray arrayWithObject:#""] forKey:#"images"];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
NSLog(#"%#",#"attempting to create an array to store the images in");
}
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSLog(#"Image on didenterbackground: %#", imageView);
self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView5.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 = [[UIImage alloc] initWithData:[self.array objectAtIndex:0]];
imageView2.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:1]];
imageView3.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:2]];
imageView4.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:3]];
imageView5.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:4]];
imageView6.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:5]];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
backToGalleryButton.hidden = YES;
tapToDeleteLabel.hidden = YES;
deleteButton1.hidden = YES;
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.user = nil;
}
////end of saving
///// shows the hidden and invisible "delete" button over each photo.
- (IBAction)editButtonPressed:(id)sender {
grabButton.hidden = YES;
editButton.hidden = YES;
backToGalleryButton.hidden = NO;
tapToDeleteLabel.hidden = NO;
deleteButton1.hidden = NO;
}
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
NSLog(#"Array: %#, index: %d", self.array, alertView.tag);
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
#end
EDIT: This is the code I use to put the objects into the UIImageView from the users camera roll:
- (IBAction)grabImage {
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
_popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
[_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentModalViewController:imgPicker animated:YES];
}
[self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView2.image == nil) {
imageView2.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView3.image == nil) {
imageView3.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView4.image == nil) {
imageView4.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
}
When I added NSLog(#"Array: %#, index: %d", self.array, alertView.tag); just before removeAtIndex the console says 2012-04-03 18:39:39.066 AppName[1631:f803] Array: (null), index: 0. Could that be the cause? I'm not sure why it would be, I think the code looks fine.
Removing the image from the array is not the only step you have to take. Your code is correct for removing the image from the array, which is why you get image out of bounds the second time, but you also need to remove the image from the UI so the user can no longer delete an image that is not there.
There are many oddities with this code but I think the problem is that you are not calling super on your viewwillappear and viewdidload functions. I would get rid of your viewWillAppear method as it serves no purpose.

-initWithContentsOfFile: for an NSMutableArray

I stored images in an NSMutableArray, and now I'm trying to get them to show up in viewDidLoad. I tried calling initWithContentsOfFile, but that doesn't seem to work. This is how the code looks:
imageView.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:0]];
I'm not sure what I should use instead of initWithContentsOfFile to have the saved images load, I'm not even sure if I can save images in a plist through user defaults. I've been researching it for awhile now to no avail. Any help is much appreciated, thanks!
EDIT: Here is additional code:
- (IBAction)grabImage {
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
_popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
[_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentModalViewController:imgPicker animated:YES];
}
[self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (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;
}
if (imageView3.image == nil) {
imageView3.image = img;
[self.array addObject:imageView3.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.array addObject:imageView3.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 = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:0]];
imageView2.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:1]];
imageView3.image = [[UIImage alloc] initWithContentsOfFile:[self.array objectAtIndex:2]];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
backToGalleryButton.hidden = YES;
tapToDeleteLabel.hidden = YES;
deleteButton1.hidden = YES;
[super viewDidLoad];
}
EDIT: This is how I'm tagging the images and deleting them based upon their tags:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (UIImageView *)viewForTag:(NSInteger)tag {
UIImageView *found = nil;
for (UIImageView *view in self.array) {
if (tag == view.tag) {
found = view;
break;
}
}
return found;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
NSLog(#"The tag is %i", alertView.tag);
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
}
NSLog(#"After deleting item, array count = %d", [array count]);
NSLog(#"Returned view is :%#, in view: %#", [self.view viewWithTag:alertView.tag], self.view);
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:#"images"];
}
The problem is that you can't store images in a property list, which is what you're trying to do when you save it in the user defaults. You need to use an archiver to convert the image to an NSData object which you can store.
It looks like you're not passing a valid image path to the initializer method. Make sure the path is correct, and that it includes the image extension.
Really, though, you shouldn't be calling initWithContentsOfFile: in this case, because UIImageView's image property retains the image when you set it. That will usually lead to a memory leak (unless you're using automatic reference counting). Use one of the static initializers instead, such as imageNamed:, which has the added bonuses of using the system cache and also automatically loading the correct version of the image based on the characteristics of the device (for instance, it will load a higher resolution variant of the image if the device has a retina display).

iOS SDK, Objective-C, uitable only showing one cell

I have a textfield that the user inputs, then I save it with NSKeyedArchiver and pull it out to view on the table but every time I enter something in the textfield and save it, it replaces the first item in the cell, I want it to add it to the table.
in NewEntry.m where I save the data with
- (IBAction)saveButton:(id)sender {
int i = selectedSegment.selectedSegmentIndex;
app = [[UIApplication sharedApplication] delegate];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:i forKey:#"category"];
if (i == 0) {
// [userDefaults setObject:titlefield.text forKey: #"titlehomework"];
// [userDefaults setObject:detailstextfield.text forKey:#"detailshomework"];
NSMutableArray *contactArray;
contactArray = [[NSMutableArray alloc] init];
[contactArray addObject:titlefield.text];
[contactArray addObject:detailstextfield.text];
[NSKeyedArchiver archiveRootObject:
contactArray toFile:datafilePath];
}
else if(selectedSegment.selectedSegmentIndex == 1) {
[userDefaults setObject:titlefield.text forKey:#"titletextprojects"];
[userDefaults setObject:detailstextfield.text forKey:#"detailsprojects"];
}
else if (selectedSegment.selectedSegmentIndex == 2){
[userDefaults setObject:titlefield.text forKey:#"titletextappointments"];
[userDefaults setObject:detailstextfield.text forKey:#"detailsappointments"];
}
else if (selectedSegment.selectedSegmentIndex == 3){
[userDefaults setObject:titlefield.text forKey:#"titletextevents"];
[userDefaults setObject:detailstextfield.text forKey:#"detailsevents"];
}
else if (selectedSegment.selectedSegmentIndex == 4){
[userDefaults setObject:titlefield.text forKey:#"titletexttodolist"];
[userDefaults setObject:detailstextfield.text forKey:#"detailstodolist"];
}
/*[userDefaults synchronize];
titlefield.text =#" ";
detailstextfield.text =#" ";
NSLog(#"selected segment %i", i);*/
/* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Task saved!" message:#"You're all done." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, selectedSegment.selectedSegmentIndex];
[alert show];*/
[[NSNotificationCenter defaultCenter] postNotificationName:#"ValuesChanged"
object:self];
[self dismissModalViewControllerAnimated:YES];
}
NewEntry ViewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
if (__managedObjectContext == nil)
{
__managedObjectContext = [(StaticTableAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext_: %#", __managedObjectContext);
}
NSFileManager *filemgr;
NSString *docsDir;
NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
datafilePath = [[NSString alloc] initWithString: [docsDir
stringByAppendingPathComponent: #"data.archive"]];
// Check if the file already exists
if ([filemgr fileExistsAtPath: datafilePath])
{
NSMutableArray *dataArray;
dataArray = [NSKeyedUnarchiver
unarchiveObjectWithFile: datafilePath];
//titlefield.text = [dataArray objectAtIndex:0];
// detailstextfield.text = [dataArray objectAtIndex:1];
}
}
new entry ViewDidUnload:
- (void)viewDidUnload
{
[self setTitleTextfield:nil];
[self setCategory:nil];
[self setDetailstextfield:nil];
[self setTitlefield:nil];
[self setTitlefield:nil];
[self setSelectedSegment:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
And in the table controller I call it here:
tableview:
- (void)viewDidLoad
{
[super viewDidLoad];
// [self fetchRecords];
if(tablesubtitles == nil && tabledata == nil){
tablesubtitles = [[NSMutableArray alloc]init];
tabledata = [[NSMutableArray alloc] init];
}
NSFileManager *filemgr;
NSString *docsDir;
NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
datafilePath = [[NSString alloc] initWithString: [docsDir
stringByAppendingPathComponent: #"data.archive"]];
// Check if the file already exists
if ([filemgr fileExistsAtPath: datafilePath])
{
NSMutableArray *dataArray;
dataArray = [NSKeyedUnarchiver
unarchiveObjectWithFile: datafilePath];
titlestring = [dataArray objectAtIndex:0 ];
detailsstring = [dataArray objectAtIndex:1];
[tabledata addObject:titlestring];
[tablesubtitles addObject:detailsstring];
}
}
and:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"homeworkcell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"homework"];
}
NSString *cellValue = [tabledata objectAtIndex:indexPath.row];
NSString *subtitle = [tablesubtitles objectAtIndex:indexPath.row];
cell.textLabel.text= cellValue;
cell.detailTextLabel.text= subtitle;
cell.textLabel.font = [UIFont systemFontOfSize:14.0];
cell.textLabel.backgroundColor = [ UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
//[tabledata addObjectser.title];
//[tabledata addObject:user.detai/s];
//static NSString *CellIdentifier = #"Cell";
// Configure the cell.
//-----------------------------------------START----------------------------Set image of cell----
cellImage = [UIImage imageNamed:#"checkboxblank.png"];
cell.imageView.image = cellImage;
//--------------------------------------------END---------------------------end set image of cell--
return cell;
}
*************UPDATE**********
So in saveButton it should be:
NSMutableArray *contactArray;
contactArray = [NSKeyedUnarchiver
unarchiveObjectWithFile: datafilePath];
// contactArray = [[NSMutableArray alloc] init];
[contactArray addObject:titlefield.text];
[contactArray addObject:detailstextfield.text];
[NSKeyedArchiver archiveRootObject:
contactArray toFile:datafilePath];
// NSDictionary *stuff;
?
The problem is that you are creating a new mutable array, putting one item in it, and then archiving that array to your file. This is going to replace whatever was there before.
To add a new item you need to unarchive the array first, add to that array, and then archive your new array.
There seems to be some core data code in here as well, there is little merit in doing your own archiving if you are going to use core data.

UIViewController presents a UINavigationController - no Nav Bar?

I have an UIViewController with a table in it. Tapping a blue disclosure icon makes the view controller present a UINavigationController. This works fine and does make the navigation controller show up, but without a navigation bar, as below:
How would I go about making that magical Navbar showing up again? I really need it to present a map in the nav controller, and right now, that does not work.
EDIT: Here's the code I use to show it:
// scanned recently table view thing
- (void)tableView:(UITableView *)tableVieww didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableVieww deselectRowAtIndexPath:indexPath animated:YES];
if(indexPath.section == 0) {
NSString *info = [[scannedBackups objectAtIndex:indexPath.row] objectForKey:#"data"];
NSArray *items = [info componentsSeparatedByString:#"&"];
scanCodeViewCohntroller.dict = [[NSMutableDictionary alloc] init];
int o;
for (o = 0; o < [items count]; o++) {
NSArray *secondItems = [[items objectAtIndex:o] componentsSeparatedByString:#"="];
[scanCodeViewCohntroller.dict setObject:[secondItems objectAtIndex:1] forKey:[secondItems objectAtIndex:0]];
}
/*NSError *err;
scanCodeViewCohntroller.dict = [NSPropertyListSerialization propertyListWithData:[foo dataUsingEncoding:NSUnicodeStringEncoding] options:NSPropertyListMutableContainersAndLeaves format:kCFPropertyListXMLFormat_v1_0 error:&err];
if(err != nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Corrupted Data" message:[NSString stringWithFormat:#"Your Scanned Backup Data Store is corrupted. It will now be erased. %#", [err localizedDescription]] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
scannedBackups = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/scannedCodes.plist", documentsDirectory];
[scannedBackups writeToFile:fullFileName atomically:NO];
[tableView reloadData];
}*/
[scanCodeViewCohntroller.dict setObject:[[scannedBackups objectAtIndex:indexPath.row] objectForKey:#"date"] forKey:#"date"];
[scanCodeViewCohntroller initalizeData];
[self presentModalViewController:scanCodeViewCohntroller animated:YES];
}
}
You need to get the navigation controller and invoke setNavigationBarHidden:animated:. So, try:
[detailController.navigationController setNavigationBarHidden:NO animated:NO];
Edit:
Based on your edit, I would suggest replacing the final line:
[self presentModalViewController:scanCodeViewCohntroller animated:YES];
with:
[self.navigationController pushViewController:scanCodeViewCohntroller animated:YES];