Identifying a UISegmentedControl Inside a UITableViewCell - iphone

I am trying to work with a segmented control inside a a tableview, then when a user selects an item, I'd like to show a spinner, while some info posts to a webservice.
The problem that I am having is: How do I add a delegate and access the referenced segmented Control, so I can set it's alpha or visibility to NO? Also, what's the best practice for this, I know there's tags, but not sure how they work in this type of situation.
NSArray * segmentItems= [NSArray arrayWithObjects: #"one", #"two", #"three", #"four", #"five", nil];
UISegmentedControl *segmentedControl= [[[UISegmentedControl alloc] initWithItems: segmentItems] retain];
segmentedControl.segmentedControlStyle= UISegmentedControlStyleBar;
segmentedControl.selectedSegmentIndex= -1;
[segmentedControl addTarget: self action: #selector(onSegmentedControlChanged:) forControlEvents: UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(2, 0, 300, 30);
segmentedControl.tintColor= [UIColor grayColor];
Here's my delegate
- (IBAction)onSegmentedControlChanged:(id)sender
{
int clickedSegment= [sender selectedSegment];
}
How do I access the UISegmentedControl from the sender so I can set the visibility Off? I can always set the my object that populates my segmentedControl by extending it, I Just need to figure out how to get a reference to the the cell and the SegmentedControl?

When you create/return the cell with the segmented control, set the delegate object before returning the cell to the table.
Edit:
Sorry, misread the question. The sender passed to the delegate methods will be the actual UISegmentedControl instance you need to identify. Inside the delegate method, cast the generic sender to a UISegmentedControl` then set its attributes as needed.
The selected table row is passed to the tableview selection methods.

Related

EXC_BAD_ACCESS when trying to get selectedSegmentIndex of UISegmentedControl

I'm programmatically adding a UISegmentedControl to my UINavigationBar as follows
UISegmentedControl *toggleSwitch = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects: #"Bar", #"Scatter", nil]];
toggleSwitch.segmentedControlStyle = UISegmentedControlStyleBar;
[toggleSwitch addTarget:self action:#selector(toggleSwitched:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:toggleSwitch];
self.navigationItem.rightBarButtonItem = buttonItem;
[toggleSwitch release];
[buttonItem release];
I then have a method, toggleSwitched to handle the events:
-(void) toggleSwitched:(id) sender {
if([sender isKindOfClass:[UISegmentedControl class]]) {
NSLog(#"%#",((UISegmentedControl*)sender).selectedSegmentIndex );
}
}
From my reading of the Apple Documentation, this is the proper way to set up the event handling for the touch event.
HOWEVER, when I run the program (in the simulator) and tap the segments, the following things happen:
If it's the first segment (index 0), 'null' is logged to the console
If it's the second segment (index 1), the program crashes with EXC_BAD_ACCESS
When I look in the variables window of the debugger, sender is of type UISegmentedControl and the _selectedSegment property appears to be correct (0 or 1).
What am I improperly accessing and how can I set up my delegate function to switch between the two values of the UISegmentedController?
Your NSLog is wrong. selectedSegmentIndex returns NSUInteger, so you need to use #"%d" instead of #"%#". %# is for objects, so the system is trying to use the number as a memory address that points to a object, and generating an error for you.

UITableViewCell with TextField and checks input

I am currently create a UITableViewCell with a UITextField in it.
On click of the text field, I want to bring up a number keyboard that I created. And as I type, the textfield should check the input for me; on click of other place, the keypad should be dismissed.
Code:
UITableViewCell *sizeCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"sizeCell"];
sizeCell.textLabel.text = #"Size";
UITextField* sizeField = [[UITextField alloc] initWithFrame:CGRectMake(185, 10, 100, 28)];
sizeField.text = #"0";
sizeField.textAlignment = UITextAlignmentRight;
sizeField.textColor = [UIColor colorWithRed:50.0/255.0 green:79.0/255.0 blue:133.0/255.0 alpha:1.0f];
sizeField.backgroundColor = [UIColor clearColor];
sizeField.keyboardType = UIKeyboardTypeDecimalPad;
[sizeCell.contentView addSubview:sizeField];
rows = [[NSArray arrayWithObjects:switchCell, typeCell, sizeCell, nil] retain];
I tried to implement UITextFieldDelegate like:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[sizeField resignFirstResponder];
return YES;
}
but the keyboard doesn't go away...
How do I validate the input and dismiss the keyboard?
You never set the delegate on your textfield so that textFieldShouldReturn: gets called. Make sure your class conforms to UITextFieldDelegate and then do the following:
...
UITextField* sizeField = [[UITextField alloc] initWithFrame:CGRectMake(185, 10, 100, 28)];
sizeField.delegate = self; //This is important!
sizeField.text = #"0";
...
A few observations:
As another poster suggested, make sure you set the keyboard's delegate correctly.
If you want to dismiss the keyboard on keyboard return, make sure you have one on your custom keyboard and it's correctly set up to call the ...ShouldReturn method.
If you want to dismiss on taps outside, you'll have to do that on your own.
You are declaring sizeField inside the method where you are setting it up, then calling it from another method outside that scope. I assume you have a class variable called sizeField or you'd be getting a compiler error. However, declaring it again when you're setting it up like you do shadows the class variable declaration so it never gets set up. Incidentally, that's a memory leak.
This shouldn't affect the actual running of the program if all else is correct (but it will if, e.g. 4 is the problem and not fixed), but I think it's better form to call [textField resign...] instead of [sizeField resign...]. At the least you should assert(textField == sizeField).

How to check whether the UISegmentedControl is selected or not by user?

I got an app in which I allocate 5 UISegmentedControl dynamically into the view. And got a Done button at the end. My condition that to proceed into next step (when done button is pressed), all the UISegmentControls "should be selected by user".
The default selection in segmentcontrol is none.
How to check whether all the UISegmentedControls in my view is selected by the user before action on the done button is executed?
Right from the apple document, this should answer your question:
#property(nonatomic) NSInteger selectedSegmentIndex
Discussion
The default value is UISegmentedControlNoSegment (no segment selected) until the user touches a segment.
Hope you can use that to check whether the value is user selected or not, to prevent going to next page.
NSLog(#"%i", self.segment.selectedSegmentIndex);
this results -1 if no segment is selected.
add target and action to your segmentControls for UIControlEventValueChanged.
From the selector you gave in action, check which segmentControl was changed, and set it's corresponding flag (ex: array of string which are #"0" for not selected and #"1" once selected).
At any time check which flags are not set, the corresponding segmentControls were never selected.
This is how u create an UISegmentedControl
NSArray *itemArray = [NSArray arrayWithObjects: #"Title1", #"Title2", #"Title3", #"Title4",nil];
segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.frame = CGRectMake(0, 0, 310, 35);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.selectedSegmentIndex = 0;
[segmentedControl addTarget:self action:#selector(pickOne:) forControlEvents:UIControlEventValueChanged];
segmentedControl.tintColor=[UIColor grayColor];
Then to find which segment was selected,
NSString *category =[segmentedControl titleForSegmentAtIndex: [segmentedControl selectedSegmentIndex]];
if(category==#"Title1"){
//Do something here..
}
Hope this helps.... Happy Coding

Having Problem with dynamically created UITextField in iphone sdk

In my iphone app, I have created some UITextField in scrollView dynamically. And added one button in xib. On that button's TouchUpInside event, I opened UIImagePickercontroller to open photo library and taking selected image on UIImageView.
Now when modalview is dissmissed, values in my UITextField disappears.
How do I retain the UITextField values?
txt = [[UITextField alloc] initWithFrame:CGRectMake(10.0f, 30.0f, 200.0f, 30.0f)];
[txt addTarget:self action:#selector(keyDown:)forControlEvents:UIControlEventEditingDidEndOnExit];
txt.textColor = [UIColor blackColor];
txt.borderStyle = UITextBorderStyleBezel;
txt.autocorrectionType = UITextAutocorrectionTypeNo;
[fieldArray addObject:txt];
Using for loop I am adding txt to NSMutableArray fieldArray.
Here is the code where I fetch values from TextFields
NSMutableArray *insertValues = [[NSMutableArray alloc]init];
//Taking values from textFields
for (int i=1; i<=nooffields; i++) {
UITextField *tf = (UITextField *)[self.view viewWithTag:i];
NSLog(#"TF : %#",tf.text);
if (tf.text.length<=0) {
tf.text=#"";
}
[insertValues addObject:[NSString stringWithFormat:#"'%#'",tf.text]];
}
EDIT :
And also when I display values from database in this textFields and try to edit it. It gives me null values.
What may be the reason? If there any other alternatives? please help me
UITextField *textField=[[UITextField alloc]init];
[textField setFrame:CGRectMake(x,y, width, hight)];
[textField setBorderStyle:UITextBorderStyleRoundedRect];
[self.view addSubview:textField];
The information that your scrollview uses to get populated should be stored outside the scrollview, in a NSMutableDictionary for example. So everytime cellForRowAtIndexPath gets called it can retrieve the information from that source. So I advise you to store the UITextField's text within the dictionary. You can index it by its tag number. That way you won't loose whatever it contained.
I hope it helps you
Cheers
I finally got a work around for my problem.
I am temporarily storing my textField's values into database when presentModalViewController is called.
These values I retrieve back into the textFields on viewWillAppear.
This may not be a very efficient solution but it worked in my case.
Hope this helps someone.
Thanks for all your responses.

If I add a UISwitch control to each of my table view cells, how can I tell which cell it belongs to?

I have a UITableView with cells that contain a UISwitch control. It's similar to the table view in the iPhone's Clock app shown below...
(source: epicself.com)
In my app's cellForRowAtIndexPath method, I create and attach the UISwitch control like so...
CGRect frameSwitch = CGRectMake(215.0, 10.0, 94.0, 27.0);
UISwitch *switchEnabled = [[UISwitch alloc] initWithFrame:frameSwitch];
[switchEnabled addTarget:self action:#selector(switchToggled:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = switchEnabled;
My question is, when the switch is toggled by the user and the switchToggled method is called, how can I tell which table cell it belongs to? I can't really do much with it without knowing it's context.
Thanks so much in advance for your help!
In your action method, you can cast the superview of the passed-in UISwitch (which is the UITableViewCell itself), then pass that to the tableView's indexPathForCell method.
indexPathForCell will return a NSIndexPath object, which you can then use to index to your datamodel to modify. Then all you gotta do is call reloadData on your tableView.
Also, in cellForRowAtIndexPath, you should set the UISwitch's state based on your model.
First of all, fix the memory leak:
UISwitch *switchEnabled = [[[UISwitch alloc] initWithFrame:frameSwitch] autorelease];
Then pick one of these options:
switchEnabled.tag = someInt; // before adding it to the cell
NSLog(#"switched %d",switch.tag); // to see which switch was toggled
or
UITableViewCell *parentCell = switchEnabled.superview;
// + some magic to see which cell this actually is