UITextfield in UITableview with Calendar value - ios

I have a question about populating UITableViewCell with the selected value in calendar. So i have this tableview which is of course created when the view appears, and as i said i also i have this calendar view controller. The main idea is that users can select a date on the calendar, and after that that value should appear in the text field in tableview.
I've have a function that is returning the selected value from the calendars view controller to that other view controller, but after that i can't populate the UITextField with that value.
Any idea or previous similar experience?
Here is the code that is used in the calendar view controller
-(void)giveString:(NSString*)string{
GradesViewController *grades = [[GradesViewController alloc]init];
[grades getString:string];
NSLog(#"String : %#",string);}
and here is the class in that other view in which i want this string value from calendar in my textfield located in tableviewcell
-(void)getString:(NSString*)string{
stringDate = string;
NSLog(#"String: %#",stringDate);}
the both values appear in log...

You are never retaining "string" in [GradesViewController getString:string]
-(void)getString:(NSString*)string {
stringDate = string;
[stringDate retain];
NSLog(#"String: %#",stringDate);
}
Make sure it's released as well in order to ensure that garbage collection will clean it up.

you need to set the stringDate value in cellForRowAtIndexpath, if you are declared that textfield in your tableviewcell cellForRowAtIndexpath. If you are using custom tableviewcell, you need to pass that value to you custome tableView cell class, like how you are calling from CalendarViewController to other ViewController
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellId = #"cellId";
UITableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (tableCell == nil) {
tableCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
UITextField *urlTxtFld = [[UITextField alloc] initWithFrame:CGRectMake(70, 10, 230, 120)];
urlTxtFld.backgroundColor = [UIColor clearColor];
urlTxtFld.text = stringDate // you need to set your text like this
urlTxtFld.autocorrectionType = UITextAutocorrectionTypeNo;
[qrCell addSubview:urlTxtView];
[urlTxtFld release];
}
}

Related

UITableViewCell Custom Add to favourites button issue

in my table view, i placed a custom "Add to Favs" button in every cell to enable the user to copy the exact cell content to a second tableview controller. when you hit the "Add to Favs" button an alert view shows up to ask if you want to copy the cell and paste it to the second view controller or not. now there are two things.
1- is there a way to delete the "Add to Favs" button permanently from that cell if "OK" is selected from the alert view to indicate that the cell is copied and pasted to the second tableview? - so the user won't be able to add the cell content over and over again.
2- this is the bigger question: how would i copy and paste the cell content to the secondtableview controller with "Add to Favs" click?
here is the way my cells re configured:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
NSString* letter = [letters objectAtIndex:indexPath.section];
NSArray* arrayForLetter = (NSArray*)[filteredTableData objectForKey:letter];
Songs* songs = (Songs*)[arrayForLetter objectAtIndex:indexPath.row];
cell.textLabel.text = songs.name;
cell.detailTextLabel.text = songs.description;
CGSize itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIButton *addtoFavsButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
addtoFavsButton.frame = CGRectMake(200.0f, 5.0f, 105.0f, 70.0f);
[addtoFavsButton setImage:[UIImage imageNamed:#"fav.png"] forState:UIControlStateNormal];
[addtoFavsButton setTintColor:[UIColor whiteColor]];
[cell addSubview:addtoFavsButton];
[addtoFavsButton addTarget:self
action:#selector(addtoFavs:)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (IBAction)addtoFavs:(id)sender
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Dikkaaaat!"
message:#"Şarkıyı Favori Akorlarınıza Alıyorsunuz..."
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[alert show];
}
Considering the data is in the app only, and considering you are using a regular table cell, not a custom one, what I would recommend is:
Make a new simple array in your app called "myFavorites" or whatever, which will hold just a list of numerical values.
When the user confirms to add to favorites, take the current section and row indexes from the songs array, and store in this new array.
In your first view controller, add to your "cellForRowAtIndexPath" a simple check to see if the song for that row exist in the new array with.
Something like:
if([[myFavorites objectAtIndex:indexPath.section] containsObject:[NSString stringWithFormat:#"%ld", (long)indexPath.row]]){
// Don't make button because is already a favorite.
}else{
// Make button because not yet a favorite.
}
Your second table view will be almost identical, except near the top of your "cellForRowAtIndexPath", do a similar check:
if([[myFavorites objectAtIndex:indexPath.section] containsObject:[NSString stringWithFormat:#"%ld", (long)indexPath.row]]){
// Is a favorite, so put regular cell stuff here to have the cell show
....
}else{
// Not a favorite, don't generate cell.
cell.visible = NO;
return cell;
}
There are other things you can do but it would require changing your setup from a regular cell to a custom cell with a new class and properties blah blah, so is a little more complicated to implement, but would still amount to practically the same output/processing.
Firstly, you aren't copying and pasting - you're referencing. Specifically you're saying that some of your songs are special.
Secondly, the user should be able to tell if they're special, and be able to toggle it. Dispense with the alert, just show the state on the button and toggle the special setting on and off as its tapped.
Now, the second table view works in th same way as the first, it just filters the songs to decide what to display.
You need to decide how to mark each song as special, probably by adding a Boolean property to the class and saving it with the rest of the data. An alternative would be to have a separate list of song IDs (or unique names).
If you want to change you cell, you need make the custom view as a #property.
#property (nonatomic, strong) UIView *cellContent;
then setup in cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[cell.contentView addSubview:[self setupCellContentView:indexPath]];
return cell;
}
- (UIView *)setupCellContentView:(NSIndexPath *)indexPath
{
if (!_cellContent) {
_cellContent = [[UIView alloc] initWithFrame:CGRectZero];
}
// do sth like you did in cellForRowAtIndexPath//
return _cellContent;
}
then you can manipulate the cell.contentView in alertView:clickedButtonAtIndex:
and pass the view #property (nonatomic, strong) UIView *cellContent to next viewController
ps:After you remove the "Add to Favs" button from the _cellContent,don't forget
[_cellContent removeFromSuperview];
[tableView reloadData];
To answer the first question, YES you can remove the "Add to Favs" button from cell object but it will create issue with you rest of the songs display because of the fact that UITableView reuses the cell objects. So if you mark a cell favourite and remove it's button, any upcoming row which will reuse this object will not be able to show that favourite button to user. So you better discard this approach.
To maintain or copy the content of a cell, which is nothing but a reference to a Songs object in you master array, you can create another array of fav songs and add those Songs objects to this array. Now you can remove this song object from your master array and reload the table data. This approach is suitable if you are using 2 different table views for data display.
If you are displaying both type of songs in one table view by indicating through "Fav Icon", then you should add a BOOL property to Songs model object and set it when you confirm with alert view.

Programmatically created textfields will not save text

SITUATION:
My two textfields are being declared in my .h file:
#interface DetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate, UITextFieldDelegate> {
UITextField *countTotalFieldUniversal;
UITextField *flavorNameUniversal;
}
And instantiated in my .m file:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
// Label default cell
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
//Text fields used for editing
countTotalFieldUniversal = [[UITextField alloc] initWithFrame:CGRectMake(200, 10, 85, 30)];
countTotalFieldUniversal. delegate = self;
flavorNameUniversal = [[UITextField alloc] initWithFrame:CGRectMake(10, 8, 280, 30)];
flavorNameUniversal.delegate = self;
flavorNameUniversal.text = #"Flavor";
countTotalFieldUniversal.text = #"Count";
ATTEMPTS TO DEBUG:
When I try to print the current textfield value in setEditing using this code:
NSString *flavorText = ((UITextField*)[self.view viewWithTag:1]).text;
NSString *countText = ((UITextField*)[self.view viewWithTag:2]).text;
NSLog(#"newFlavorName: %#", flavorText);
NSLog(#"newCountTotal: %#", countText);
I only get the unedited, original labels: "Flavor" and "Count".
When I try to print the current textfield values in setEditing using this code:
NSString * newFlavorName = flavorNameUniversal.text;
NSString * newCountTotal = countTotalFieldUniversal.text;
NSLog(#"newFlavorName: %#", newFlavorName);
NSLog(#"newCountTotal: %#", newCountTotal);
I get null values for both!
It's like my changes to the text field aren't tracked at all!
Most likely your changes for the text field AREN'T being tracked at all! At least they are being tracked and then released before you get your hands on them.
Don't instantiate a new UITextField object every time. I suggest you subclass UITableViewCell to handle ownership and drawing of the two UITextField's. Give your subclass a two text field properties (#property (strong, nonatomic) UITextField *textField1/2) and make sure to instantiate them either in init or use lazy instantiation in the setter.
Use delegation (the textFieldDidEndEditing: method declared in the UITextFieldDelegate protocol) to get the data from your UITextField to your viewController.
That SHOULD work and track the changes made to the text field.

Access properties of a UITableViewCell from the UIViewController

I'm coding an app that has a UITableView inside a UIViewController. The UITableView uses prototype cells, which inside of each one is a UITextField. The view, as you may guess, is a form that the user's going to fill in.
When the user clicks a button in the UI, an event should be fired where all the text values from each one of the UITextFields that are being displayed is collected so the data can be sent to the server.
I'm having trouble accessing the cell's UITextField property so I can grab the text value.
Part of my code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIDentifier = #"Cell";
AddCardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIDentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[AddCardCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIDentifier];
}
cell.campoTextField.placeholder = [placeholders objectAtIndex:indexPath.row];
cell.tituloLabel.text = [titulosCampos objectAtIndex:indexPath.row];
return cell;
}
The setup of my data source:
titulosCampos = [NSArray arrayWithObjects: #"Nombre", #"Correo", nil];
placeholders = [NSArray arrayWithObjects: #"Oscar Swanros", #"dev#swanros.com", nil];
You can retrieve the text which is stored in all cells campoTextField, then use this code.....
NSMutableArray *titulosCampoTextArray = [[NSMutableArray alloc] init];
for (int i = 0; i < titulosCampos.count; i++) {
AddCardCell *cell = (AddCardCell*)[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
[titulosCampoTextArray addObject:cell.campoTextField.text];
}
NSLog(#"Data in titulosCampoText array %#",titulosCampoTextArray);
hope this will helps you..:-)
I'm assuming your AddCardCell is the text field's delegate. The best approach for this is for your cell class to declare a delegate protocol of its own. Your view controller would then be the cell's delegate. Your cell should then implement the text field's delegate method to detect when the text has changed. Then the cell should tell its delegate that there is new text. The text should be one of the parameters in the delegate method. Your view controller would implement this cell delegate method. The view controller would then update the data model with the updated text.
When the button is tapped, the text from all of the cells will already be in the data model.

Why does my custom UITableViewCell never change from the prototype?

I have a custom class that extends UITableViewCell. It has two labels and a UISegmentedControl.
Here is the cellForRowAtIndexPath() that I configured. When I inspect "cell" in the debugger it has all the data I'm providing. But somehow that data never gets applied.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
CustomGameCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CustomGameCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MyData *my_data = [rows objectAtIndex:indexPath.row];
UILabel *my_date = [[UILabel alloc] init];
my_date.text = my_data.myDate;
[cell setMyDateLabel:my_date];
UILabel *my_question = [[UILabel alloc] init];
my_question.text = my.question;
[cell setMyQuestionLabel:my_question];
UISegmentedControl *my_choices = [[UISegmentedControl alloc]
initWithItems:[NSArray arrayWithObjects:my.firstChoice, my.secondChoice, nil]];
[my_choices setSelectedSegmentIndex:my.choice];
[cell setMyChoiceSegments:my_choices];
return cell
}
The data that I want displayed is currently in an array I create in viewDidLoad() which is accessible to cellForRowAtIndexPath() through the "rows" var.
When I run the code in the simulator I get three rows in the table representing the three elements in the array I created in viewDidLoad(). However, the content of those rows look exactly like what I defined in the storyboard.
What am I missing?
Where are you defining the layout of your cell? In a NIB? In your storyboard? Programmatically in your initWithStyle of CustomGameCell? The implementation details vary a little based upon which approach you use, but you definitely need to either define NIB or prototype cell in your storyboard, or programmatically create the controls, set their frames, perform addSubview so they're included in the cell, etc.
Your code is adding new UILabel objects, not adding them as a subview to anything, doing it regardless if you're using a dequeued cell or not, etc. So there are numerous problems here. To see examples of how you might properly use a custom cell, see Customizing Cells in the Table View Programming Guide. But, like I said, the details vary a bit based upon how you're designing your subclassed UITableViewCell layout, so I hesitate to propose any code until you specify how you're designing your user interface.
You must have added the labels and segmentcontrol in the cells content view of the cell, if not then please do so.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
CustomGameCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CustomGameCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MyData *my_data = [rows objectAtIndex:indexPath.row];
cell.myDateLabel.text = my_data.myDate;
cell.myQuestionLabel.text = my.question;
[cell.myChoiceSegments setSelectedSegmentIndex:my.choice];
[cell autorelease];
return cell
}
Also use autorelease for the memory management.

Problems Updating content of table cell

I was just playing around with IOS and I hit a problem and it seems so simple that I can't believe it's not working
I have a table list
I have set up all the delegate so that it displays information from a plist
that works
however when I switched to my custom view for the internal layout, I get the default text of the view but not the text form the plist
Here is some code of the table view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DefaultCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DefaultCell"];
}
EmergencyContactItemConrtroller *genericViewController = [[EmergencyContactItemConrtroller alloc] initWithNibName:#"EmergencyContactItemConrtroller" bundle:nil];
[genericViewController setInitialParametersWithTitle:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Title"]
withCatption:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Caption"]
withNumber:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Number"]
withOtherInfo:nil];
[cell.contentView addSubview:genericViewController.view];
return cell;
}
and here is the code of setInitialParametersWithTitle in the cell view controller.
-(void) setInitialParametersWithTitle:(NSString *)title
withCatption:(NSString *)caption
withNumber:(NSString *)number
withOtherInfo:(NSDictionary *)otherInfo{
self.titleLable.text = title;
self.captionLable.text = caption;
[self.numberButton setTitle:number forState:UIControlStateNormal];
}
I checked that the xib IBOutlet are linked correctly.
when I try to debug I get he right values send to the function, how ever when I printout self.titleLable.text before assigning a value to it, there is no value in it.
Any Ideas ?
Jason
EmergencyContactItemConrtroller is UIViewController class?
All IBOutlets will initialized after
[cell.contentView addSubview:genericViewController.view]
is done; Then you should change them
Try to reload your table view in -(void)viewwillappear()
Try this, inside if(cell==nil),
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DefaultCell"];
cell.contentView = [[UIView alloc]init];
}
Then you can add subView above cell's contentView

Resources