I try to understand the application to save the data. I have a custom object.
#interface CellObject : NSObject <NSCoding>
#property (nonatomic, strong) NSString *links;
#property (nonatomic, strong) NSString *title;
#property (assign) BOOL isFavorite;
#end
#import "CellObject.h"
#implementation CellObject
#synthesize title, links;
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:title forKey:#"title"];
[aCoder encodeObject:links forKey:#"links"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self){
[self setTitle:[aDecoder decodeObjectForKey:#"title"]];
[self setLinks:[aDecoder decodeObjectForKey:#"links"]];
}
return self;
}
And the controller to the table in cells which must be my objects.
#import "SettingsViewController.h"
#import "SettingsCell.h"
#import "CellObject.h"
#define kFileName #"archive"
#define kDataKey #"Data"
#implementation SettingsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = #"Settings";
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"Helvetica" size:20.0f], NSFontAttributeName, nil] forState:UIControlStateNormal];
}
return self;
}
-(NSString *)dataFilePath {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFileName];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
[_rssObjectArray removeAllObjects];
_rssObjectArray = nil;
if(!_rssObjectArray)
{
_rssObjectArray = [[NSMutableArray alloc]init];
}
_resourceTV = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
[_resourceTV setAutoresizesSubviews:YES];
[_resourceTV setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[_resourceTV setDataSource:self];
[_resourceTV setDelegate:self];
[self.view addSubview:_resourceTV];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showAlert)];
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSMutableData* data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
CellObject *cellObj = [unarchiver decodeObjectForKey:kDataKey];
[unarchiver finishDecoding];
}
}
-(void)applicationWillResignActive:(NSNotification *)notification
{
CellObject *cellObj = [[CellObject alloc] init];
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:cellObj forKey:kDataKey];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
}
- (void)showAlert
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Enter name" message:#"And internet adress" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
UITextField *bottomField = [alertView textFieldAtIndex:0];
[bottomField setPlaceholder:#"Name"];
UITextField *footerField = [alertView textFieldAtIndex:1];
[footerField setPlaceholder:#"Internet adress"];
footerField.secureTextEntry = NO;
alertView.tag = -1;
[alertView show];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _rssObjectArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [SettingsCell cellIdentifier];
SettingsCell *sCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!sCell)
{
sCell = [[SettingsCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
CellObject *object = [_rssObjectArray objectAtIndex:indexPath.row];
sCell.linkLabel.text = object.links;
sCell.nameLabel.text = object.title;
sCell.favorite.selected = object.isFavorite;
return sCell;
}
//change rows in table
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[_rssObjectArray removeObjectAtIndex:indexPath.row];
[_resourceTV deleteRowsAtIndexPaths:#[indexPath] withRowAnimation: UITableViewRowAnimationTop];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex && (alertView.alertViewStyle == UIAlertViewStyleLoginAndPasswordInput))
{
CellObject *object = nil;
if (alertView.tag == -1) {
object = [[CellObject alloc]init];
[_rssObjectArray addObject:object];
} else {
object = [_rssObjectArray objectAtIndex:alertView.tag];
}
object.links = [[alertView textFieldAtIndex:0] text];
object.title = [[alertView textFieldAtIndex:1] text];
[_resourceTV reloadData];
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Enter name" message:#"And internet adress" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
UITextField *bottomField = [alertView textFieldAtIndex:0];
[bottomField setPlaceholder:#"Name"];
UITextField *footerField = [alertView textFieldAtIndex:1];
[footerField setPlaceholder:#"Internet adress"];
footerField.secureTextEntry = NO;
CellObject *cellObj = [_rssObjectArray objectAtIndex:indexPath.row];
bottomField.text = cellObj.links;
footerField.text = cellObj.title;
alertView.tag = indexPath.row;
[alertView show];
}
#end
On the Internet find tutorials, but they are not very helpful, tell me how to do so would object persists after restarting the application, they remained in the cells?
In your viewDidLoad:
- (void)viewDidLoad
{
// ...
if ([[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) { // Check if the file exist.
NSMutableData* data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]]; // Retrieve the data from the file
self.rssObjectArray = [[NSKeyedUnarchiver unarchiveObjectWithData:data] mutableCopy];
}
}
And your
- (NSString *)dataFilePath
{
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"CustomFeed.plist"];
/*BOOL result = [NSKeyedArchiver archiveRootObject:self.rssObjectArray toFile:path];
// This line above erase the file when it's called, remove all the code i commented.
if(result == YES)
{
NSLog(#"Array saved");
}*/
return path;
}
With these modifications, i tested your application and it's work.
Related
I have created a app that fetches information from a blog. I am able to successfully fetch the information and show it in the tableview. Then i created a search bar and a search display controller so that i could search through the information. When i run it, there is no error and it fetches and shows the information. But when i enter a letter into the searchbar there is no cells in the tableview even though there is words starting from that letter.
This is the code in my .m file
#implementation EventsTableViewController
#synthesize searchBar, filteredEventsArray, eventNamesArray, isFiltered, eventsDictionary;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.eventNamesArray = [NSMutableArray array];
self.eventsDictionary = [NSMutableDictionary dictionary];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self searchForEvents];
}
//Json Parsing
- (void)searchForEvents
{
NSString *eventsSearchUrlString = [NSString stringWithFormat:#"https://www.googleapis.com/blogger/v3/blogs/1562818803553764290/posts?key=AIzaSyBTOxz-vPHgzIkw9k88hDKd99ILTaXTt0Y"];
NSURL *eventsSearchUrl = [NSURL URLWithString:eventsSearchUrlString];
NSURLRequest *eventsSearchUrlRequest = [NSURLRequest requestWithURL:eventsSearchUrl];
NSURLSession *sharedUrlSession = [NSURLSession sharedSession];
NSURLSessionDataTask *searchEventsTask =
[sharedUrlSession dataTaskWithRequest:eventsSearchUrlRequest completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),
^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if(error)
{
UIAlertView *searchAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your internet connection" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[searchAlertView show];
}
else
{
NSString *resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Search results: %#", resultString);
NSError *jsonParseError = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if(jsonParseError)
{
UIAlertView *jsonParseErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:jsonParseError.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[jsonParseErrorAlert show];
}
else
{
for(NSString *key in jsonDictionary.keyEnumerator)
{
NSLog(#"First level key: %#", key);
}
[self.eventNamesArray removeAllObjects];
[self.eventsDictionary removeAllObjects];
NSArray *searchResultsArray = [jsonDictionary objectForKey:#"items"];
//NSLog(#"test%#",searchResultsArray);
for(NSDictionary *eventsInfoDictionary in searchResultsArray)
{
Events *event = [[Events alloc] init];
event.eventName = [eventsInfoDictionary objectForKey:#"title"];
event.eventDescription =[eventsInfoDictionary objectForKey:#"content"];
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
NSString *eventsAsStrings = [event.eventName substringToIndex:1];
NSMutableArray *eventsInArray = [self.eventsDictionary objectForKey:eventsAsStrings];
if(!eventsInArray)
{
eventsInArray = [NSMutableArray array];
[self.eventNamesArray addObject:eventsAsStrings];
}
[eventsInArray addObject:event];
[self.eventsDictionary setObject:eventsInArray forKey:eventsAsStrings];
if ([event.eventDescription containsString:#"<br />"]) {
NSString* eventDescrip = event.eventDescription;
NSString* stringWithoutHTMLtags = [eventDescrip stringByReplacingOccurrencesOfString:#"<br />" withString:#""];
event.eventDescription = stringWithoutHTMLtags;
}
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
}
[self.eventNamesArray sortedArrayUsingComparator:^NSComparisonResult(Events *obj1, Events *obj2) {
Events *time1 = obj1;
Events *time2 = obj2;
if (time1 > time2) {
return (NSComparisonResult)NSOrderedDescending;
}
else if (time1 < time2) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
[self.tableView reloadData];
}
}
});
}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[searchEventsTask resume];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
isFiltered = NO;
}
else {
isFiltered = YES;
}
for (NSString *eventName in eventNamesArray) {
NSRange eventNameRange = [eventName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (eventNameRange.location != NSNotFound) {
[filteredEventsArray addObject:eventName];
}
}
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (isFiltered == YES) {
return filteredEventsArray.count;
}
else {
return self.eventNamesArray.count;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *eventsWithFirstLetter;
if (isFiltered == YES) {
NSString *firstLetter = [self.filteredEventsArray objectAtIndex:section];
eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
else {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:section];
eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"eventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Events *event;
if (isFiltered == YES) {
NSString *firstLetter = [self.filteredEventsArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
}
else {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
DescriptionViewController *descriptionViewController = (DescriptionViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"descriptionController"];
descriptionViewController.eventNameDesc = event.eventDescription;
descriptionViewController.navigationItem.title = event.eventName;
[self.navigationController pushViewController:descriptionViewController animated:YES];
}
#end
I have created a app that fetches information from a blog and shows it in the app. After i fetch the data it is supposed to be shown on the table view. It shows the things that i have posted but the things are in alphabetical order rather than the time i posted the thing.
Here is the code
#implementation EventsTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.firstLettersArray = [NSMutableArray array];
self.eventsDictionary = [NSMutableDictionary dictionary];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self searchForEvents];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self searchForEvents];
}
- (void)searchForEvents
{
[self.searchBar resignFirstResponder];
NSString *eventsSearchUrlString = [NSString stringWithFormat:#"https://www.googleapis.com/blogger/v3/blogs/1562818803553764290/posts?key=AIzaSyBTOxz-vPHgzIkw9k88hDKd99ILTaXTt0Y"];
NSURL *eventsSearchUrl = [NSURL URLWithString:eventsSearchUrlString];
NSURLRequest *eventsSearchUrlRequest = [NSURLRequest requestWithURL:eventsSearchUrl];
NSURLSession *sharedUrlSession = [NSURLSession sharedSession];
NSURLSessionDataTask *searchEventsTask =
[sharedUrlSession dataTaskWithRequest:eventsSearchUrlRequest completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),
^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if(error)
{
UIAlertView *searchAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[searchAlertView show];
}
else
{
NSString *resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Search results: %#", resultString);
NSError *jsonParseError = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if(jsonParseError)
{
UIAlertView *jsonParseErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:jsonParseError.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[jsonParseErrorAlert show];
}
else
{
for(NSString *key in jsonDictionary.keyEnumerator)
{
NSLog(#"First level key: %#", key);
}
[self.firstLettersArray removeAllObjects];
[self.eventsDictionary removeAllObjects];
NSArray *searchResultsArray = [jsonDictionary objectForKey:#"items"];
//NSLog(#"test%#",searchResultsArray);
for(NSDictionary *eventsInfoDictionary in searchResultsArray)
{
Events *event = [[Events alloc] init];
event.eventName = [eventsInfoDictionary objectForKey:#"title"];
event.eventDescription =[eventsInfoDictionary objectForKey:#"content"];
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
NSString *eventsFirstLetter = [event.eventName substringToIndex:1];
NSMutableArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:eventsFirstLetter];
if(!eventsWithFirstLetter)
{
eventsWithFirstLetter = [NSMutableArray array];
[self.firstLettersArray addObject:eventsFirstLetter];
}
[eventsWithFirstLetter addObject:event];
[self.eventsDictionary setObject:eventsWithFirstLetter forKey:eventsFirstLetter];
if ([event.eventDescription containsString:#"<br />"]) {
NSString* eventDescrip = event.eventDescription;
NSString* stringWithoutHTMLtags = [eventDescrip stringByReplacingOccurrencesOfString:#"<br />" withString:#""];
event.eventDescription = stringWithoutHTMLtags;
}
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
}
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
[self.tableView reloadData];
}
}
});
}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[searchEventsTask resume];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.firstLettersArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *firstLetter = [self.firstLettersArray objectAtIndex:section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"eventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
NSLog(#"Row selected %#",cellText);*/
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
DescriptionViewController *descriptionViewController = (DescriptionViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"descriptionController"];
descriptionViewController.eventNameDesc = event.eventDescription;
descriptionViewController.navigationItem.title = event.eventName;
[self.navigationController pushViewController:descriptionViewController animated:YES];
}
#end
You are trying to sort firstLettersArray which contain Events objects by using standard sort: function which doesn't know how to work with your custom objects.
You can use sortedArrayUsingComparator: function like this:
[firstLettersArray sortedArrayUsingComparator:^NSComparisonResult(Events *obj1, Events *obj2) {
// return object comparison result here
}];
Edit: Also you need to have NSDate property in Events class and feel it with event created time. I believe event created time should be contained in eventsInfoDictionary. Eventually you will be able to compare obj1 and obj2 using NSDate property.
i think this line not working
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
use this line of code may help you....
sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
I have a UITableViewController that I'm using for a form. Each cell has a UILabel and a UITextField. When I tap on a UITextField, the keyboard comes up, then I scroll down and the cell goes off screen, when I tap on another UITextField, the app crashes.
This is my cell subclass.
#implementation EditorFieldCell
- (id)init
{
self = [super init];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self.contentView addSubview:self.nameLabel];
[self.contentView addSubview:self.textField];
}
return self;
}
- (void)setName:(NSString *)name
{
_name = name;
CGRect frame = self.nameLabel.frame;
frame.size.width = roundf([_name sizeWithFont:[UIFont boldSystemFontOfSize:17.0f]].width);
self.nameLabel.frame = frame;
frame = self.textField.frame;
frame.size.width = self.frame.size.width - 16.0f - 14.0f - 14.0f - self.nameLabel.frame.size.width;
frame.origin.x = 16.0f + 14.0f + self.nameLabel.frame.size.width;
self.textField.frame = frame;
self.nameLabel.text = _name;
}
- (void)setPlaceholder:(NSString *)placeholder
{
_placeholder = placeholder;
self.textField.placeholder = placeholder;
}
- (void)setText:(NSString *)text
{
_text = text;
self.textField.text = text;
}
- (UILabel*)nameLabel
{
if (_nameLabel)
{
return _nameLabel;
}
_nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(16.0f, 0.0f, 0.0f, self.frame.size.height)];
_nameLabel.font = [UIFont boldSystemFontOfSize:17.0f];
return _nameLabel;
}
- (UITextField*)textField
{
if (_textField)
{
return _textField;
}
_textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, self.frame.size.height)];
_textField.font = [UIFont systemFontOfSize:17.0f];
_textField.textAlignment = NSTextAlignmentRight;
_textField.keyboardAppearance = UIKeyboardAppearanceDark;
return _textField;
}
#end
And here is my table subclass.
#interface ManageWineViewController ()
#end
#implementation ManageWineViewController
- (id)init
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
self.title = #"Manage Wine";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(done)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:self action:#selector(save)];
NSMutableArray *data = [[NSMutableArray alloc] init];
NSMutableDictionary *section = [[NSMutableDictionary alloc] init];
NSMutableArray *sectionData = [[NSMutableArray alloc] init];
[sectionData addObject:#{#"name": #"Estate", #"placeholder": #""}];
[sectionData addObject:#{#"name": #"Wine", #"placeholder": #""}];
[sectionData addObject:#{#"name": #"Vintage", #"placeholder": #"", #"keyboardType": [NSNumber numberWithInt:UIKeyboardTypeDecimalPad]}];
[section setObject:sectionData forKey:#"data"];
[data addObject:section];
section = [[NSMutableDictionary alloc] init];
sectionData = [[NSMutableArray alloc] init];
[sectionData addObject:#{#"name": #"Type"}];
[sectionData addObject:#{#"name": #"Style", #"placeholder": #"Select a Style", #"options": #[#"", #"Red", #"White", #"Rosé", #"Sparkling", #"Saké", #"Dessert, Sherry, and Port"]}];
[sectionData addObject:#{#"name": #"Appellation", #"placeholder": #""}];
[section setObject:sectionData forKey:#"data"];
[data addObject:section];
section = [[NSMutableDictionary alloc] init];
sectionData = [[NSMutableArray alloc] init];
[sectionData addObject:#{#"name": #"Alcohol %", #"placeholder": #"", #"keyboardType": [NSNumber numberWithInt:UIKeyboardTypeDecimalPad]}];
[section setObject:sectionData forKey:#"data"];
[data addObject:section];
self.data = data;
self.inputTexts = [[NSMutableDictionary alloc] initWithDictionary:#{#"0": #"",
#"1": #"",
#"2": #"",
#"10": #"",
#"11": #"",
#"12": #"",
#"20": #""}];
}
return self;
}
- (void)done
{
[self.currentTextField resignFirstResponder];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)save
{
[self done];
}
- (void)hidePicker
{
[self.selectActionSheet dismissWithClickedButtonIndex:0 animated:YES];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.data.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ((NSArray*)[[self.data objectAtIndex:section] objectForKey:#"data"]).count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *cellInfo = [((NSArray*)[[self.data objectAtIndex:indexPath.section] objectForKey:#"data"]) objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"EditorCell";
EditorFieldCell *cell = (EditorFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[EditorFieldCell alloc] init];
}
cell.textField.tag = [[NSString stringWithFormat:#"%i%i", indexPath.section, indexPath.row] integerValue];
cell.textField.delegate = self;
cell.name = cellInfo[#"name"];
cell.placeholder = cellInfo[#"placeholder"];
cell.text = [self.inputTexts objectForKey:[NSString stringWithFormat:#"%i", cell.textField.tag]];
if (cellInfo[#"keyboardType"])
{
cell.textField.keyboardType = [cellInfo[#"keyboardType"] integerValue];
}
else
{
cell.textField.keyboardType = UIKeyboardTypeDefault;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#pragma mark - UITextFieldDelegate methods
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
self.currentTextField = textField;
if (textField.tag == 11)
{
//show select
NSArray *options = [[[[self.data objectAtIndex:1] objectForKey:#"data"] objectAtIndex:1] objectForKey:#"options"];
self.selectTextField = textField;
self.selectOptions = options;
[textField resignFirstResponder];
self.selectActionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
self.selectPickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
self.selectPickerView.showsSelectionIndicator = YES;
self.selectPickerView.dataSource = self;
self.selectPickerView.delegate = self;
[self.selectActionSheet addSubview:self.selectPickerView];
[self.selectActionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[self.selectActionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[self.inputTexts setObject:textField.text forKey:[NSString stringWithFormat:#"%i", textField.tag]];
return YES;
}
#end
The error that I am getting with the crash is:
*** -[EditorFieldCell _didChangeToFirstResponder:]: message sent to deallocated instance 0x155f6e20
This is iOS 7 (and will only support iOS 7) if that helps.
You are not initialising EditorFieldCell with reuse identifier.
EditorFieldCell *cell = (EditorFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
This condition will false.
if (!cell)
{
cell = [[EditorFieldCell alloc] init];
}
Try to create cell with reuseIdentifier
cell = [[EditorFieldCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
And write this in EditorFieldCell.m
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self == [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self.contentView addSubview:self.nameLabel];
[self.contentView addSubview:self.textField];
}
}
I know this question has been asked before but mine is different. My app has an add button and edit button that deletes/adds table views. I want every cell that is created by the user to go to the same view. I've been looking everywhere for the code but I can't find it. BTW the ____ is just a placeholder. The table coding is in the app delegate and I have a second view controller for the view that is loaded when a row is clicked.
AppDelegate.h
#interface _____AppDelegate : NSObject <UIApplicationDelegate> {
CustomCellViewController *customCellViewController;
IBOutlet UIWindow *window;
IBOutlet UITableViewCell *customCell;
NSMutableArray *data;
IBOutlet UITableView *mainTableView;
IBOutlet UINavigationItem *navItem;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#property (nonatomic, retain) CustomCellViewController *customCellViewController;
- (IBAction)addRowToTableView;
- (IBAction)editTable;
- (NSString *)dataFilePath;
#end
AppDelegate.m
#import "______AppDelegate.h"
#implementation ______AppDelegate;
#synthesize window;
#synthesize navController=_navController;
#synthesize customCellViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSArray *archivedArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[self dataFilePath]];
if (archivedArray == nil) {
data = [[NSMutableArray alloc] init];
} else {
data = [[NSMutableArray alloc] initWithArray:archivedArray];
}
// Override point for customization after application launch
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
- (IBAction)addRowToTableView {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"New Product" message:#"What is the name of your product?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alert addTextFieldWithValue:#"" label:#"Name of product..."];
UITextField *tf = [alert textFieldAtIndex:0];
tf.clearButtonMode = UITextFieldViewModeWhileEditing;
tf.keyboardType = UIKeyboardTypeURL;
tf.keyboardAppearance = UIKeyboardAppearanceAlert;
tf.autocapitalizationType = UITextAutocapitalizationTypeNone;
tf.autocorrectionType = UITextAutocorrectionTypeNo;
[alert show];
}
-(void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
UITextField *tf = [alert textFieldAtIndex:0];
[data addObject:tf.text];
[self saveData];
[mainTableView reloadData];
}
}
- (IBAction)editTable {
UIBarButtonItem *leftItem;
[mainTableView setEditing:!mainTableView.editing animated:YES];
if (mainTableView.editing) {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(editTable)];
} else {
leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editTable)];
}
navItem.rightBarButtonItem = leftItem;
[self saveData];
[mainTableView reloadData];
}
- (IBAction)endText {
}
- (NSInteger)numberOfSectionInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifer = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:"Cell"] autorelease];
}
cell.textLabel.text = [data objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)dataFilePath {
NSString *dataFilePath;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
dataFilePath = [[documentDirectory stringByAppendingPathComponent:#"applicationData.plist"] retain];
return dataFilePath;
}
- (void)saveData {
[NSKeyedArchiver archiveRootObject:[data copy] toFile:[self dataFilePath]];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[data removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath {
NSString *item = [[data objectAtIndex:fromIndexPath.row] retain];
[data removeObject:item];
[data insertObject:item atIndex:toIndexPath.row];
[item release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)dealloc {
[window release];
[_navController release];
[customCellViewController release];
[super dealloc];
}
#end
I don't mean to be harsh, but you have a lot of basics to learn. ARC will make your life much easier and your code better, by eliminating the need to manually manage memory (for the most part). You can enable it when you first start a project. You should.
Why is an App Delegate managing a table view? No, no no. The app delegate is supposed to respond to system-level events, not run your whole application. You need a separate view controller. Find some tutorials around the web and see how a basic app using a table view is structured. There are many. My favorites are on raywenderlich.com
I want developed a similar alarm application to remind user send message, and my question is I want get user field in data like numbers, message and date to table view by array.
I do this use tabbar controller,my first view is gave to user field in all data and check save button. My second view is table view to remind user.
Now I can save the data in NSMutableArray by one time only, where I save the data again, the old data with replace. Anyone know how to do this?
My code here.
Here is save button for another view.
I call FirstView
- (IBAction)SaveAll:(id)sender{
if(numText.text == nil || textView.text == nil || Selectime == nil){
NSLog(#"error becos value null");
UIAlertView *errorview = [[UIAlertView alloc]initWithTitle:#"Error Info" message:#"You nomber , message text or date no input or select.Pls fill in all. "delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorview show];
[errorview release];
}else{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (localNotif == nil)
return;
DataClass *obj=[DataClass getInstance];
localNotif.fireDate = obj.showdate;
NSString *getdate = [obj.showdate description];
[defaults setObject:getdate forKey:#"date"];
NSLog(#"localNotif = %#", localNotif.fireDate);
localNotif.timeZone = [NSTimeZone localTimeZone];
obj.showdate = nil;
NSString *getnum =numText.text;
[defaults setObject:getnum forKey:#"keyToLookupString"];
// Notification details
// localNotif.alertBody = [eventText text];
NSString *getmessage = self.textView.text;
[defaults setObject:getmessage forKey:#"message"];
localNotif.alertBody = self.textView.text;
NSLog(#"alertBody message = %#",localNotif.alertBody);
// Set the action button
localNotif.alertAction = #"Send Now?";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
numText.text = #"";
textView.text = #"";
Selectime.text = #"";
self.textView.placeholder = NSLocalizedString(#"Event Here....",);
SaveDataView *savedata = [[SaveDataView alloc]initWithNibName:#"SaveView" bundle:nil];
[savedata.tableview reloadData];
}
}
In my table view controller I call SaveDataView.
SaveDataView.h
#import <UIKit/UIKit.h>
#interface SaveDataView : UIViewController <UITableViewDataSource,UITableViewDelegate>{
IBOutlet UITableView *tableview;
NSMutableArray *MessageArray;
NSMutableArray *NomberArray;
NSMutableArray *DateArray;
}
#property (nonatomic, retain) IBOutlet UITableView *tableview;
#property (nonatomic,retain)NSMutableArray *MessageArray;
#property (nonatomic,retain)NSMutableArray *NomberArray;
#property (nonatomic,retain)NSMutableArray *DateArray;
#end
SaveDataView.m
#import "SaveDataView.h"
#import "DataClass.h"
#import "SMSAppDelegate.h"
#implementation SaveDataView
#synthesize tableview;
#synthesize MessageArray,NomberArray,DateArray;
- (void) viewWillAppear {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *messageShow =[defaults stringForKey:#"message"];
NSString *nomberShow = [defaults stringForKey:#"keyToLookupString"];
NSString *dateShow = [defaults stringForKey:#"date"];
[MessageArray addObject:messageShow];
NSLog(#"MessageArray = %#",MessageArray);
[NomberArray addObject:nomberShow];
NSLog(#"NomberArray = %#",NomberArray);
[DateArray addObject:dateShow];
NSLog(#"DateArray = %#",DateArray);
[self.tableview reloadData];
NSLog(#"checking.... ");
//[super viewWillAppear:animated];
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSLog(#"table view viewDidLoad");
MessageArray = [[NSMutableArray alloc] init];
NomberArray = [[NSMutableArray alloc] init];
DateArray = [[NSMutableArray alloc] init];
// [MessageArray insertObject:messageShow atIndex:[MessageArray count]];
[self viewWillAppear];
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
//return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
NSLog(#"in nsinteger tableview");
return [self.MessageArray count];
return [self.NomberArray count];
return [self.DateArray count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"in uitableviewcell...");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// if (cell == nil) {
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
//}
// Configure the cell...
//NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
//UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
// NSString *enNote = [[NSString alloc] initWithString:string];
NSString *showmessage = [MessageArray objectAtIndex:indexPath.row];
NSString *shownomber = [NomberArray objectAtIndex:indexPath.row];
NSString *showdate = [DateArray objectAtIndex:indexPath.row];
[cell.textLabel setText:showmessage];
NSLog(#"table view settext = %#",showmessage);
cell.textLabel.textColor = [UIColor blackColor];
NSString *abc = [NSString stringWithFormat:#"%# \n %#", shownomber,showdate];
//NSString *abc = [NSString stringWithFormat:#"%# \n %#", nomber,[notif.fireDate description]];
[cell.detailTextLabel setText:abc];
cell.detailTextLabel.numberOfLines = 2;
NSLog(#"table view detailTextLabel = %#,%#",shownomber,showdate);
cell.detailTextLabel.textColor = [UIColor redColor];
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
return cell;
[self.tableview reloadData];
}
#end
Replace the viewDidLoad with viewWillappear...viewDidLoad is called only once when you loaded the view so you cant able to replace the array. viewWillappear is called everytime when the view is appeared on the screen...
EDIT:afer seeing the comments.
keep the viewdidload as it is . add these codes to your application.
-(void)viewwillappear
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *messageShow =[defaults stringForKey:#"message"];
NSString *nomberShow = [defaults stringForKey:#"keyToLookupString"];
NSString *dateShow = [defaults stringForKey:#"date"];
[MessageArray addObject:messageShow];
NSLog(#"MessageArray = %#",MessageArray);
[NomberArray addObject:nomberShow];
NSLog(#"NomberArray = %#",NomberArray);
[DateArray addObject:dateShow];
NSLog(#"DateArray = %#",DateArray);
}