I have this delegate method below that is setting a few fields in my tableview. What happens is when one of the tableview cells is pressed it loads a subview with a bunch more tableview cells when one is selected is pops the view from the viewcontrollerand loads the value that was selected into the parentviews cell that was initially selected.
This main cell effects what I am able to set in the second cell. so when it is clicked it shows data related to the first selection.
I am enabling my user to go back to any of the cells to change their selection.. or maybe they might go back thinking they want to change but don't.
In which case for the second tableviewcell of my parentview will either need to change if the first cell changes or stay the same if the value of the first cell dosnt change.
I have this delegate that is used with the first cell, and it is where I am trying to control the value of the secondcell, as shown below.
- (void) setManufactureSearchFields:(NSArray *)arrayValues withIndexPath:(NSIndexPath *)myIndexPath
{
manufactureSearchObjectString = [[arrayValues valueForKey:#"MANUFACTURER"] objectAtIndex:0];
manufactureIdString = [[arrayValues valueForKey:#"MANUFACTURERID"] objectAtIndex:0]; //Restricts Models dataset
manufactureResultIndexPath = myIndexPath;
[self.tableView reloadData]; //reloads the tabels so you can see the value in the tableViewCell.
//need some sort of if statment here so that if the back button is pressed modelSearchObjectString is not changed..
if (oldManufactureSearchObjectString != manufactureSearchObjectString) {
modelResultIndexPath = NULL;
modelSearchObjectString = #"empty";
oldManufactureSearchObjectString = manufactureSearchObjectString;
}
}
The thing being is that it enters the if statment every time even if the same cell is selected for the first cell.. (in which case is should not enter the if statement.
I thought I could do this by checking oldMan vrs man if != then go through and set the second cell stuff and then pass man to oldMan so next time you use the first cell it has a value to comapre against. but obviously this dosn't seem to be working. Is my logic bad or is it something in my code.
this is how I set these values in .h they are all #synthesised
//...
NSString *manufactureSearchObjectString;
NSString *oldManufactureSearchObjectString;
NSString *manufactureIdString;
NSIndexPath *manufactureResultIndexPath;
//...
#property (copy) NSString *manufactureSearchObjectString;
#property (copy) NSString *oldManufactureSearchObjectString;
#property (copy) NSString *manufactureIdString;
#property (copy) NSIndexPath *manufactureResultIndexPath;
//...
You have to compare the value of the NSStrings as below:
BOOL isEqual = [aString isEqualToString:bString]; // provide aString and bString
if (!isEqual)
{
// code
}
What you've done is to compare the pointers, which can be different for strings of the same value.
Related
I have a UITableView with each cell is having a UITableViewCellAccessoryCheckmark. The user can check and uncheck the cells depending on his preference. The user can check/select multiple cells in the tableview. A selected/checked cell can be unchecked and rechecked again on user preference.
I have a done button in the UITableViewController. On its click, I need to return to the previous view, before that I have to have a collection of the text in the checked cells(only checked cells).
How can I do this.
I was planning on developing a logic, by keeping an NSMutableArray and update it on - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath, when a cell gets checked/selected. But when every time a cell is unchecked I have to remove the item from the array and if the cell is checked again, then I have to add it again. I reckon thats not the right way to do this. What would be the right way to do this.
I couldn't find a question of similar kind here in Stackoverflow, which is very unusual. Would be helpful if someone could post a link, if the question was asked before.
Maintain two arrays, like this:
#property (nonatomic, retain) NSMutableArray *features, *selectedFeature;
synthesize them in .m file. initialize your both arrays something like this in viewDidLoad:
self.features = [NSArray arrayWithMyOwnResourceLikeDownloadedFromServerOrWhatever];
self.selectedFeature = [NSMutableArray array];
Then do something like this in didSelectRowAtIndex:
NSString * stirng = [features objectAtIndex:indexPath.row];
if ([self.selectedFeature containsObject:stirng]) {
[self.selectedFeature removeObject:stirng];
}
else{
[self.selectedFeature addObject:stirng];
}
and in your cellForRowAtIndexPath:
NSString * stirng = [features objectAtIndex:indexPath.row];
[cell.textLabel setText:stirng];
if ([self.selectedFeature containsObject:stirng]) {
//it is selected feature
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else{
//it is un-selected feature
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
Create a boolean array of the same length as the number of checkable cells and update the value on click events. If the table content is dynamic, you can use methods provided by NSMutabeArray to keep the boolean array in accordance with the table content. Upon return use the array to grab the text you need.
Hey
Just wondering how do you..
Iv created some code that automatically creates a certain amount of UITextField input by the user.
Each UITextfield has a set tag automatically created.
The user then inputs his value into each of the UITextFields.
I want to retrieve the input text from the UITextFields which correspond to the tag.
I thought I nearly had it with:
NSString * tmpV = (NSString*)[choiceTextField.text viewWithTag:result];
where result is a increment, choiceTextField is the UITextField. With this I get a problem not defining instance, which I can't do as the UITextFields are generated in code not on the xib.
So to sum up, basically want the retrieve the text from a UITextField with specific tag.
Thanks
Dan
UITextField *yourTextField = (UITextField *)[self.view viewWithTag:result];
NSString *getText = myTextField.text;
Hope this helps
Your textfields must be a subview of a parent view. You need to write the following in your view controller of the parent view:
NSString *text = ((UITextField*)[self.view viewWithTag:result]).text;
Just go with Hetal Vora's solution: looks much cleaner!
-viewWithTag can be called on any view and searches all its subviews for one that matches the tag. Thus, you will find your UITextField by calling it on any view that is above it in the hierarchy. For example, you could call it on the view controller's view that contains your text field, as follows:
NSString *tmpV = [[myViewController.view viewWithTag:result] text];
If you are already in the view controller's class you could use:
NSString *tmpV = [[self.view viewWithTag:result] text];
On second thought, the following may be more correct & will avoid any compiler errors:
UITextField *myTextField = (UITextField *)[self.view viewWithTag:result];
NSString *tmpV = myTextField.text;
Caveat: I have looked for the answer to my question and several come close, but I'm still missing something. Here is the scenario:
I want a way to create UITableViewCells that contain UISwitches dynamically at run time, based on the data in a table (which I can do). The problem becomes connecting the switches such that I can get their value when that view is changed (navigated away, closed, etc). I have tried to use the events UIControlEventValueChanged to be notified, but have failed to specify it correctly, because it dumps when that switch is tapped. Also, there doesn't seem to be any way to uniquely identify the switch so that if all the events are handled by a single routine (ideal), I can't tell them apart.
So...
If I have a UITableView:
#interface RootViewController : UITableViewController
{
UISwitch * autoLockSwitch;
}
#property (nonatomic, retain) UISwitch * autoLockSwitch;
-(void) switchFlipState: (id) sender;
#end
// the .m file:
#implementation RootViewController
// ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
int row = 0;
NSString * label = nil;
TableCellDef_t * cell_def = nil;
row = indexPath.row;
cell_def = &mainMenuTableCellsDef[ row ];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
label = (NSString *) mainMenuTableCellsDef[indexPath.row].text;
[cell.textLabel setText:(NSString *) mainMenuItemStrings[ indexPath.row ]];
if (cell_def->isSpecial) // call special func/method to add switch et al to cell.
{
(*cell_def->isSpecial)(cell ); // add switch, button, etc.
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
}
and this is the 'special' function:
-(void) autoLockSpecialItem :(UITableViewCell *) cell
{
autoLockSwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
[autoLockSwitch addTarget:self action:#selector(switchFlipState:) forControlEvents:UIControlEventValueChanged ];
[cell addSubview:autoLockSwitch];
cell.accessoryView = autoLockSwitch;
}
and finally:
-(void) switchFlipState: (id) sender
{
NSLog(#"FLIPPED");
}
==============================================================
Questions:
Why would it crash (bad selector) when the switch was tapped? I believe that my code follows all the example code that I have seen, but obviously something is wrong.
I cannot put a instance method into a table as a function pointer; and it doesn't seem to like a class method either. If I make it a 'C/C++' function, how do I get access to the class/instance member variables? That is, if I want to put a call to autoLockSpecialItem into a static table (or reasonable facsimile) such that I can get autoLockSwitch member variable? If I make it a class method and the autoLockSwitch var a static, will that be valid?
More simply: how do I connect the UIControlEventValueChanged to my view (I have tried and failed) and can I differentiate at runtime within the event handler which switch has changed?
Is there a better way? I cannot believe that I am the first person to have to solve this type of problem.
Apologies for the length, appreciation for attention and grateful for any and all help.
:bp:
Don't know about why your method isn't connected, but a simple way to "differentiate at runtime within the event handler which switch has changed" is to take the (id)sender given to your event handler, walk your tableview, and compare the sender to any switches, if present, in each table item. If that's too slow, a hash table connecting senders to table cells, or something like that, is a possible optimization.
If you want to use C function pointers, you need to pass the object to the function to use it to call the object's property accessor methods within the function. (Or you could assign the object to a global variable if it's clearly a singleton, but that's a very politically incorrect answer.)
First, and easy way to define your different switches would be defining their tag based on the row number. When one of the switches is tapped you can access sender.tag to get the row number this way.
Also, you should probably be adding the switch the the cells content view, not the actual cell, [cell.contentView addSubview:autoLockSwitch]. Also the frame does need to be set (note CGRectZero, cocoa will ignore the width and height but uses the x,y coords to define where you want the switch in the cell.
I have two customized cells in an iphone UITableViewController and would like to capture the data in one cell into another.
I am currently unable to post images and please assume the following points.
There are two custom UITableViewcells
Notes Textfield in one customcell
Submit button in another text field.
Now I want to pass data typed in the notes textfield to be available when I click the Submit button. Is this possible? Please help :(
In general you should store your data separate from views. So if you have some table controller there must data objects like array or dictionary or array of dictionaries. And when you click submit you should get associated data object and work with it.
In your case when textfield lose focus you must get textfield value and store it in your data store.
UPD: It not very clean but can help at first
- (void) textFieldDidEndEditing: (UITextField *) textField {
// At first need to get cell. findSuperviewWithClass is custom method to find proper superview object
MyCellClass *cell = (MyCellClass*)[textField findSuperviewWithClass:[MyCellClass class]];
// and indexPath for it
NSIndexPath *index = [tableView indexPathForCell:cell];
// tableData is NSArray of my objects
MyDataObjClass *dataObj = [tableData objectAtIndex:index.row];
dataObj.text = textField.text;
}
I have a UIButton that is created inside of each table cell. I want to hook up a touch event like so:
[imageButton addTarget:self
action:#selector(startVote:)
forControlEvents:UIControlEventTouchUpInside];
I want to pass data about the current row (the id of the object for that row) to the startVote method. Is there a method that I am missing to do this or am I breaking some best practice. This seems like a very normal thing to do?
I assume you have some sort of NSArray with the data that gets passed on to the buttons in cellForRowAtIndexPath.
Try this in startVote:
- (void)startVote:(id)sender {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *myData = [myArray objectAtIndex:indexPath.row];
}
EDIT:
If for some reason the row is not selected, you can assign a unique tag to every button upon creation and then:
- (void)startVote:(id)sender {
int myTag = [(UIButton *)sender tag];
NSDictionary *myData = [myArray objectAtIndex:myTag];
}
Maybe you would do some sort of operation with the tag so it can be used as an index (I add a certain amount to every tag so it will not conflict with "automatic" tagging used by the OS.
The UITableViewCell doesn't know, out of the box, what row it's displaying in the table. Remember, the intent is that the same cell instances are re-used all over the table to display its data. That said, your UITableViewController is responsible for setting up the cells and passing them to the system (and has the index path, of course). You could, at that point, do something like:
Assuming it's a custom cell class, set a property on the cell instance to identify what row it's displaying, and which your button can later use.
If you're putting these buttons in the cells as their accessory views, take a look at the table delegate's tableView:accessoryButtonTappedForRowWithIndexPath: method.
If it's a one-section table, you could do something really cheesy like store the row index in the button's tag property. Your startVote: method is passed the button, and could then extract its tag.