Realtime Values in UITableViewCell from UIDatePicker - objective-c

I have a UIViewController with two UI Components: UITableView and UIDatePicker. My goal is, to create a screen like the ical->add->Start & End.
I added the the tableView delegate and dateSource to my header file. In the implementation file, I want to display the current value from the datePicker in my tableCell (like the iCal Start & End screen).
My .m looks like the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[datePicker addTarget:self action:#selector(datePickerValueChanged) forControlEvents:UIControlEventValueChanged];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSMutableArray *dict = [dictionary objectForKey:#"DATA"];
if(indexPath.row == 1){
UISwitch *switchSpecifyEnd = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = switchSpecifyEnd;
[(UISwitch *)cell.accessoryView setOn:NO]; // Or NO, obviously!
[(UISwitch *)cell.accessoryView addTarget:self action:#selector(switchSpecifyEnd)
forControlEvents:UIControlEventValueChanged];
cell.textLabel.text = [dict objectAtIndex:indexPath.row];
}else if(indexPath.row == 3){
UISwitch *switchOpenEnd = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = switchOpenEnd;
[(UISwitch *)cell.accessoryView setOn:NO]; // Or NO, obviously!
[(UISwitch *)cell.accessoryView addTarget:self action:#selector(switchOpenEnd)
forControlEvents:UIControlEventValueChanged];
cell.textLabel.text = [dict objectAtIndex:indexPath.row];
}else{
cell.textLabel.text = [dict objectAtIndex:indexPath.row];
// NSLog(#"Update Cell: %#",<but how>);
}
return cell;
}
- (void)datePickerValueChanged{
NSLog(#"Logging: %#", [NSString stringWithFormat:#"%#",datePicker.date]);
}
How can I update my tableCell with the value from the datePicker?
BR,
mybecks

For updating your table cell you need to reload your table and when your table will reload then cellForRowAtIndexPath will get call and you can update your cell text.
Suppose this is your method that gets called when you select some date in date picker
-(IBAction)setStartTimeMethod
{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EEE MMM dd, yyyy hh:mm a"];
self.startTimeString = [dateFormat stringFromDate:[timeStartPicker date]];
[dateFormat release];
[optionsTableView reloadData];
}

Related

Instruments/ Leaks show [_NSCoreManagedObjectID allocateBatch:Count:]

I am getting a crash when i go back and forth in navigation controller where one has a tableview. I used instruments to see what is going on and i see that when i go back to the first view controller i get
[_NSCoreManagedObjectID allocateBatch:Count:] leaks. Here is the screenshot from Instruments
The more i go back and forth the more leaks come up. What would be the reason for this? I set nsfetchedresultcontroller to nil in viewdidunload, but i don't set it to nil when i go between tabs.
Thanks!
UPDATE:
I did some testing and i found that if i comment
Person *person = [self.fetchedResultsController objectAtIndexPath:indexPath];
in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"personCell";
PeopleListTableViewCell *cell = (PeopleListTableViewCell *) [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PeopleListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
Person *person = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.personName.text = person.fullname;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy"];
NSDate *tmpDate = person.dateofbirth;
NSString *strDate = [dateFormatter stringFromDate:tmpDate];
cell.personDateOfBirth.text = strDate;
NSString *imgURL=[person.imageurl stringByAppendingString:#"?maxheight=120&maxwidth=156"];
[cell.personImage setImageWithURL:[NSURL URLWithString:imgURL] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
return cell;
}
The leak goes away. I am using this tableviewcontroller as a delegate to a tableview in a different uivewcontroller.
This is how i set it when the button is clicked to show this table
- (void)signPeople
{
self.signInfoView.hidden = YES;
self.pplTableView.hidden = NO;
self.hud = [[ATMHud alloc]initWithDelegate:self];
[self.hud setActivity:YES];
self.hud.shadowEnabled = YES;
[self.view addSubview:self.hud.view];
[self.hud show];
if(!self.pplListTableViewController){
self.pplListTableViewController = [[PeopleListTableViewController alloc]init];
}
self.pplListTableViewController.delegate = self;
self.pplTableView.delegate = self.pplListTableViewController;
self.pplTableView.dataSource = self.pplListTableViewController;
//shows the People List
[self.pplListTableViewController setupFetchResultsController];
[self.pplTableView reloadData];
[self.pplTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES]; //scroll to top
}
I tried to nil out the tableview here and there and also dealloc the labels and person class nothing helps. What could be keeping the people class from getting freed. thanks!

Objective-C, iOS SDK, NSMutableArray, add elements and save data

Basically, every time I enter something in my textfield and save it to the table, the previous entry will be replaced by the new one. How do I add elements in a mutable array and save the last entry? I tried
[tabledata addObject....
and in the entry
tabledata.lastObject objectAtIndex...
but that didn't work.
here is what I have:
-(void)viewDidLoad
{
[super viewDidLoad];
titlestring = [[NSUserDefaults standardUserDefaults] objectForKey:#"titlehomework" ];
detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:#"detailshomework"];
tabledata = [[NSMutableArray alloc] initWithObjects:titlestring, nil];
tablesubtitles = [[NSMutableArray alloc] initWithObjects:detailsstring, nil];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return [tabledata count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"homeworkcell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"homeworkcell"];
}
cell.textLabel.text = [tabledata objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [tablesubtitles objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14.0];
cell.textLabel.backgroundColor = [ UIColor clearColor ];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
//-----------------------------------------START----------------------------Set image of cell----
cellImage = [UIImage imageNamed:#"checkboxblank.png"];
cell.imageView.image = cellImage;
//--------------------------------------------END---------------------------end set image of cell--
return cell;
}
Without seeing more code, the best I can do is suggest something like this
[tabledata addObject:newTitle];
[tablesubtitles addObject:newSubtitle];
[tableView reloadData];
This assumes both newTitle and newSubtitle are the NSStrings you wish to add and that tableView is the pointer to the UITableView.

How to sort a NSMUtableArray consisting of strings of date/time values?

The NSMutableArray (inboxFaxItems)consists of strings set up like: MM/DD/YYYY hh:mm:ss a
for example:
2/2/2011 2:46:39 PM
2/4/2011 11:59:47 AM
I need to be able to sort this array so that the newest dates are at the top.
#import <UIKit/UIKit.h>
#interface InboxTableViewController : UITableViewController<NSXMLParserDelegate> {
//all of these need to be put in custom class
NSMutableArray *inboxFaxItems;
NSMutableArray *dateArray;
NSMutableArray *inboxMessageID;
NSMutableArray *inboxMessagePageCount;
NSMutableArray *inboxMessageFrom;
NSMutableData *xmlData;
NSURLConnection *connectionInprogress;
NSMutableString *inboxFaxesString;
UIActivityIndicatorView *activityIndicator;
}
-(void) loadInbox;
#end
- (void)dealloc {
[inboxFaxItems release];
inboxFaxItems = nil;
[inboxMessageID release];
inboxMessageID = nil;
[inboxMessagePageCount release];
inboxMessagePageCount = nil;
[inboxMessageFrom release];
inboxMessageFrom = nil;
[dateArray release];
dateArray = nil;
[super dealloc];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [dateArray count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"InboxFaxItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
[[cell textLabel]setText:[dateArray objectAtIndex:[indexPath row]]];
cell.imageView.image = [UIImage imageNamed:#"document.png"];
return cell;
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection{
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
[parser release];
//do sorting here
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"MM/DD/YYYY hh:mm:ss a"];
for (NSString *dateString in inboxFaxItems) {
NSDate *date = [formatter dateFromString:dateString];
if (date) [dateArray addObject:date];
// If the date is nil, the string wasn't a valid date.
// You could add some error reporting in that case.
}
[[self tableView] reloadData];
[connectionInprogress release];
connectionInprogress = nil;
[xmlData release];
xmlData = nil;
}
However I am getting errors:
2011-06-29 02:49:28.782 app[4388:207] -[__NSDate isEqualToString:]: unrecognized selector sent to instance 0x4d9e090
2011-06-29 02:49:28.784 app[4388:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDate isEqualToString:]: unrecognized selector sent to instance
OK THIS SEEMS TO HAVE FIXED IT: (UPDATE)
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"InboxFaxItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm:ss a"];
NSDate *date = [dateArray objectAtIndex:[indexPath row]];
NSString *dateStr = #"";
dateStr = [formatter stringFromDate:date];
[[cell textLabel]setText:dateStr];
cell.imageView.image = [UIImage imageNamed:#"document.png"];
return cell;
}
Here's your problem:
[[cell textLabel] setText:[dateArray objectAtIndex:[indexPath row]]];
setText: assumes it gets a string, and as such, when deciding wether or not to update itself, it sends an isEqualToString: method to the object it is passed, but SURPRISE!: It's an NSDate object. Which doesn't respond to that selector, obviously.
What you need to do is to make a string from the date before you pass it to the label, and everything will come up roses.
- (NSString *)descriptionWithLocale:(id)locale
is probably the correct method for achieving this; but it's possible that
- (NSString *)description
will do all the relevant locale stuff automagically.

How can I present a picker view just like the keyboard does?

I want a UIPickerView to show up when I press a button (just like keyboard) and then go away when user taps anywhere on the screen. How can I do this? Thanks.
A bit more background: I have a UITextField called months in UITableViewCell. Now the best option for me is to put a UIPikcerView there and it will be easier for the user to just chose the month rather than having to type it out (and it's the better way). But UIPickerView looks really ugly in a UITableViewCell, not to mention I can't change it's gigantic size. So what should I do in this case?
This is how you should use UIPickerView for a textField in a UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle= UITableViewCellSelectionStyleNone;
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.clearsOnBeginEditing = NO;
textField.textAlignment = UITextAlignmentRight;
textField.delegate = self;
[cell.contentView addSubview:textField];
//textField.returnKeyType = UIReturnKeyDone;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
// if you want a UIPickerView for first row... then do the following //
// Here.. packSizePickerView is an object of UIPickerView
if (indexPath.row == 1)
{
textField.tag=0;
textField.delegate= self;
packSizePickerView.delegate = self;
packSizePickerView = [[UIPickerView alloc] init];
packSizePickerView.autoresizingMask=UIViewAutoresizingFlexibleWidth;
packSizePickerView.showsSelectionIndicator=YES;
textField.inputView = packSizePickerView;
}
// if you want to select date / months in row 2, go for UIDatePickerView //
if (indexPath.row == 1)
{
textField.tag = 1;
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChangedd:) forControlEvents:UIControlEventValueChanged];
datePicker.tag = indexPath.row;
textField.delegate= self;
textField.inputView = datePicker;
[datePicker release];
}
}
// Configure the cell...
NSInteger row = [indexPath row];
cell.textLabel.text = [myArray objectAtIndex:row];
return cell;
}
And for datePickerValueChangedd
- (void)datePickerValueChangedd:(UIDatePicker*) datePicker{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 50, 68, 68)];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
label.text = [NSString stringWithFormat:#"%#",[df stringFromDate:datePicker.date]];
NSLog(#"I am inside the datePickerValueChanged - - %#", label.text);
[df release];
globalValue1 = label.text;
// use a global variable to copy the value from the pickerView. //
}
Now in the textFieldDidEndEditing:
-(void) textFieldDidEndEditing:(UITextField *)textField {
if (textField.tag ==0)
[textField setText: globalValue0];
if (textField.tag ==1)
[textField setText: globalValue1];
}
And to resign UIDatePicker, set the UIView as a UIControl and
resignFirstResponder
I think that you need to put your UIPickerView "outside" the viewable screen and animate it in when the button is pressed. I'm not really sure what the best way to get rid of it would be but you could probably listen for a tap on the parent view when the picker is visible and then animate it back out.

UITableView not refreshing appropriately

I have a selectedArray defined as a property in my file that holds which cells have been "checked". When displaying the cell I check whether or not the current cell value is in the selectedArray, and if it is, I display the UITableViewCellAccessoryCheckmark as the table's Accessory View.
The only problem is, when the user searches for through the UITableView using the UISearchBar, I ask the table to reloadData when they are done searching, and in the numberofRows method I see the right amount of objects in the selectedArray. However, the cellForRowatIndexPath method still displays the old checkmarks as if the selectedArray has never been updated.
Can anyone PLEASE help me? Here's my code -
NSArray *tempArray = [[NSArray alloc] init];
if(tableView == theTable) {
tempArray = [contactsArray objectAtIndex:indexPath.row];
} else {
tempArray = [searchfor_array objectAtIndex:indexPath.row];
}
NSString *cellValue = [tempArray objectAtIndex:0];
static NSString *CellIdentifier;
CellIdentifier = cellValue;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake(70, 30, 200, 20)];
name.text = [tempArray objectAtIndex:0];
name.backgroundColor = [UIColor clearColor];
[name setFont:[UIFont fontWithName:#"Helvetica-Bold" size:18]];
[cell.contentView addSubview:name];
[name release];
if([selectedArray containsObject:[tempArray objectAtIndex:0]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
return cell;
[cell release];
[tempArray release];
[cellValue release];
It looks as though you're setting up the cell once and reusing it. Step through the code and you should see that the if block is entered only the first time the cell is loaded.
You'll want to adjust the cell for each row, like so:
if (cell == nil) {
// Initialize cell.
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Adjust cell for each row.
if([selectedArray containsObject:[tempArray objectAtIndex:0]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Adding to Justin's answer -
You should be adding the label in the if(cell == nil) part only. You handle the accessory view OUTSIDE of that statement. Here's what it should look like -
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake(70, 30, 200, 20)];
name.text = [tempArray objectAtIndex:0];
name.backgroundColor = [UIColor clearColor];
[name setFont:[UIFont fontWithName:#"Helvetica-Bold" size:18]];
[cell.contentView addSubview:name];
[name release];
}
if([selectedArray containsObject:[tempArray objectAtIndex:0]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}