UIControlEventValueChanged not working when i tapped an already selected segment section - iphone

My aim is to trigger UIControlEventValueChanged delegate again when i tapped an already selected segment .
So i have referred the below links
uisegmentedcontrol-register-taps-on-selected-segment
maintaining-selection-in-uisegmentedcontrol
As per the links i have created a uisegmentedcontrol subclass , implemented the - (void) setSelectedSegmentIndex:(NSInteger)toValue { method and wrote the codes (from the above links).
Its worked fine with Ipad1. However the setSelectedSegmentIndex in the inherited/sub class is not triggering in Ipad2 when tapped an already selected segment!!!! however it is working fine when i tapped an unselected segment index.
The code i done is below
Main Class
ReselectableSegmentControl *firstNextSegmentedControl = [[ReselectableSegmentControl alloc] init];
firstNextSegmentedControl.frame = CGRectMake(xCordinate, 255, 188, 50);
firstNextSegmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
firstNextSegmentedControl.tag = index + 1;
[firstNextSegmentedControl addTarget:self action:#selector(firstNextThenSegmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged];
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"NoTimerCounter.png"] atIndex:0 animated:YES];
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"Timer.png"] atIndex:1 animated:YES];
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"Counter.png"] atIndex:2 animated:YES];
firstNextSegmentedControl.selectedSegmentIndex = 0;
[self.view addSubview:firstNextSegmentedControl];
[firstNextSegmentedControl release];
firstNextSegmentedControl = nil;
UISegmentSubClass .h file
#import <Foundation/Foundation.h>
#interface ReselectableSegmentControl : UISegmentedControl {
}
#end
UISegmentSubClass .m file
-(void)setSelectedSegmentIndex:(NSInteger )selectedValue{
if (selectedValue==self.selectedSegmentIndex) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
[super setSelectedSegmentIndex:selectedValue];
}
or
-(void)setSelectedSegmentIndex:(NSInteger )selectedValue{
if (self.selectedSegmentIndex == selectedValue) {
//doing my operation if tapped again the selected value.
else {
super.selectedSegmentIndex = selectedValue;
}
}
or
- (void) setSelectedSegmentIndex:(NSInteger)toValue {
if (self.selectedSegmentIndex == toValue) {
[super setSelectedSegmentIndex:UISegmentedControlNoSegment];
} else {
[super setSelectedSegmentIndex:toValue];
}
}
The all above methods are not working with Ipad2.
Any help on this issue is appreciated.
Thanks.

Phew... finally i got the solution..
I have used UITapGestureRecognizer instead of using addTarget:self action:#selector()
Now my code is looking like,
UISegmentedControl *firstNextSegmentedControl = [[UISegmentedControl alloc] init];
firstNextSegmentedControl.frame = CGRectMake(xCordinate, 255, 188, 50);
firstNextSegmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
firstNextSegmentedControl.selectedSegmentIndex = 0;
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"NoTimerCounter.png"] atIndex:0 animated:YES];
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"Timer.png"] atIndex:1 animated:YES];
[firstNextSegmentedControl insertSegmentWithImage:[UIImage imageNamed:#"Counter.png"] atIndex:2 animated:YES];
//Added UITapGestureRecognizer instead of using addTarget: method
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] init];
tapGesture addTarget:self action:#selector(firstNextThenSegmentedControlValueChanged:) ];
[firstNextSegmentedControl addGestureRecognizer:tapGesture];
[tapGesture release];
tapGesture = nil;
[self.view addSubview:firstNextSegmentedControl];
[firstNextSegmentedControl release];
firstNextSegmentedControl = nil;
-(void)firstNextThenSegmentedControlValueChanged:(UITapGestureRecognizer *)tapGesture{
UISegmentedControl *segmentControl = (UISegmentedControl *)tapGesture.view;
switch (segmentControl.selectedSegmentIndex) {
case 0:
[self doIt:segmentControl];
break;
default:
break;
}
}

Related

How to add a view on top of keyboard?

I have added a view with buttons on top of keyboard using setInputAccessoryView.
Now i want functionality like when i click button from the view i want to display a pickerView on top of keyboard. Means like adding pickerView as subview of keyboard.
How can i do this?
Make a view you want to at the top of the keyboard. You can do this from xib or manually, but I think xib will be a better option.
Then make the reference to this view by doing this
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
textField.inputAccessoryView = YOURCustomView;
return YES;
}
Whenever you want to hide this or remove this just put this
textField.inputAccessoryView = nil;
self.pickerContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 194, 320, 224)];
self.pickerContainerView.backgroundColor = [UIColor clearColor];
[self.view addSubview:self.pickerContainerView];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleBlackTranslucent;
[pickerToolbar sizeToFit];
self.lblPickerViewTitle = [[UILabel alloc] initWithFrame:CGRectMake(15, 7, 230, 30)];
self.lblPickerViewTitle.backgroundColor = [UIColor clearColor];
[self.lblPickerViewTitle setFont: [UIFont fontWithName:#"Arial-BoldMT" size:17]];
self.lblPickerViewTitle.textAlignment = UITextAlignmentLeft;
self.lblPickerViewTitle.textColor =[UIColor whiteColor];
[pickerToolbar addSubview:self.lblPickerViewTitle];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
[flexSpace release];
UIBarButtonItem *btnCancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(closePickerView:)];
[barItems addObject:btnCancel];
[btnCancel release];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:#"ShowPicker" style:UIBarButtonItemStyleBordered target:self action:#selector(donePickerView:)];
[barItems addObject:btnDone];
[btnDone release];
[pickerToolbar setItems:barItems animated:YES];
[barItems release];
[self.pickerContainerView addSubview:pickerToolbar];
And in ShowPicker Method , write code for display UIPicker
You need to create another UIWindow first:
UIWindow *newWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0,100,320,20)];
newWindow.windowLevel = UIWindowLevelStatusBar; // this will make to place your WINDOW above the keyboard
[newWindow makeKeyAndVisible]; // show the new window
// [newWindow addSubview:yourView];
like add button on keyboard you can also add view like bellow...
here you find window of keyboard and then set frame of button and also yourView and then add to keyboard
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
return YES;
}
- (void)keyboardDidShow:(NSNotification *)note {
UIButton *returnBtn = [UIButton buttonWithType:UIButtonTypeCustom];
returnBtn.frame = CGRectMake(0,-25,320,25);
returnBtn.adjustsImageWhenHighlighted = NO;
returnBtn.backgroundColor=[UIColor darkGrayColor];
returnBtn.titleLabel.textColor=[UIColor whiteColor];
[returnBtn setBackgroundImage:[UIImage imageNamed:#"keyBtn.png"] forState:UIControlStateNormal];
[returnBtn addTarget:self action:#selector(keyboardBtn:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
// if (txtTag==5) {
[keyboard addSubview:returnBtn];
}
}
-(IBAction)keyboardBtn:(id)sender{
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
// if (txtTag==5) {
[keyboard addSubview:yourView];// here add your view with frame
}
}
i hope this help you...
:)
From Jonas Schnelli's answer
UIWindow *newWindow = [[UIWindow alloc]initWithFrame:CGRectMake(0,100,320,20)];
newWindow.windowLevel = CGFLOAT_MAX; // this will make to place your WINDOW above the keyboard
[newWindow addSubview:yourView];
Just change UIWindowLevelStatusBar to CGFLOAT_MAX will be ok.

Pause the Views from Updating

Want to pause the multiple views from updating when Pause button is pressed
In h file
#property BOOL appIsPaused;
In m file
#synthesize appIsPaused;
-(void)playpauseAction:(id)sender
{
if
([audioPlayer isPlaying]){
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateSelected];
[audioPlayer pause];
appIsPaused = YES;
} else {
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
appIsPaused = NO;
[self performSelector:#selector(displayviewsAction:) withObject:nil afterDelay:11.0];
}
}
- (void)displayviewsAction:(id)sender
{
FirstViewController *viewController = [[FirstViewController alloc] init];
viewController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:viewController.view];
[self.view addSubview:toolbar];
[self performSelector:#selector(secondViewController) withObject:nil afterDelay:23];
[viewController release];
}
-(void)secondViewController {
SecondViewController *secondController = [[SecondViewController alloc] init];
secondController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:secondController.view];
[self.view addSubview:toolbar];
[self performSelector:#selector(ThirdviewController) withObject:nil afterDelay:27];
[secondController release];
}
and it goes on like this for multiple views.
Any ideas how to pause views from updating whenever pause button is pressed.
Instead of using performSelector after delay, you should consider using a NSTimer.
Like this:
Declare a NSTimer *timer ivar.
Declare a NSUInteger viewControl;
Set viewControl to 0;
On the play part of the method add this line:
timer = [NSTimer scheduledTimerWithTimeInterval:11 target:self selector:#selector(tick) userInfo:nil repeats:YES];
-(void)tick
{
switch(viewControl)
{
case 0:
[self performSelector:#selector(firstViewController) withObject:nil];
break;
case 1:
[self performSelector:#selector(secondViewController) withObject:nil];
break;
case 2:
[self performSelector:#selector(thirdViewController) withObject:nil];
break;
.
.
.
default:
break;
}
viewControl++;
if(viewControl > MAX_VIEWS)
{
viewControl = 0;
}
}
And add this line on pause action:
[timer invalidate]
It is also cleaner and let you have more control over your code.
Hope it helps.

when UISegmentcontrol item changing, why it will hide customBadge in IOS 5?

I have added custom Badge on UISegmentControl. In Xcode 4.0.2 SDK 4.3 its working fine. But in Xcode 4.2 SDK 5.0 custom badge is not shown when another item is selected. I dont know why this happens? I'm using following code for IOS 4.3 Xcode 4.0.2:
- (void)viewDidLoad {
[super viewDidLoad];
super.tableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"wallpaper.png"]];
NSLog(#"Root View Loaded");
segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
#"Home",#"Surveys",#"Results",#"Create",#"Settings",
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 310, 40);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor darkGrayColor];
segmentedControl.momentary = NO;
segmentedControl.highlighted = YES;
segmentedControl.selectedSegmentIndex = 0;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
NSArray *segmentBarArray = [NSArray arrayWithObjects:
segmentBarItem,nil];
[[self appDelegate] setSegmentedControl:segmentedControl];
[[self appDelegate] setSegmentBarArray:segmentBarArray];
[self setToolbarItems:[[self appDelegate] segmentBarArray] animated:NO];
[[self navigationController] setToolbarHidden:NO animated:YES];
[self.navigationItem setHidesBackButton:YES animated:YES];
self.navigationController.toolbar.tintColor = [UIColor blackColor];
int surveycount = [[self appDelegate] getUnreadSurveyCount];
surveyCountBadge = [CustomBadge customBadgeWithString:[NSString stringWithFormat:#"%d",surveycount]];
[surveyCountBadge setFrame:CGRectMake(105, -10, surveyCountBadge.frame.size.width, surveyCountBadge.frame.size.height)];
[segmentedControl addSubview:surveyCountBadge];
if (surveycount == 0) {
[surveyCountBadge setHidden:YES];
}else{
[surveyCountBadge setHidden:NO];
}
}
-(void)segmentAction:(id) sender{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
NSLog(#"selected index is %d",segmentedControl.selectedSegmentIndex);
if (segmentedControl.selectedSegmentIndex == 0) {
[self.navigationController popToRootViewControllerAnimated:YES];
} else if(segmentedControl.selectedSegmentIndex ==1){
surveyForMeViewController = [[SurveyForMeView alloc] initWithNibName:#"SurveyForMeView" bundle:nil];
[self.navigationController pushViewController:surveyForMeViewController animated:YES];
} else if(segmentedControl.selectedSegmentIndex ==2){
resultViewController = [[ResultView alloc] initWithNibName:#"ResultView" bundle:nil];
[self.navigationController pushViewController:resultViewController animated:YES];
} else if (segmentedControl.selectedSegmentIndex ==3) {
newSurveyViewController = [[NewSurveyView alloc] initWithNibName:#"NewSurveyView" bundle:nil];
[self.navigationController pushViewController:newSurveyViewController animated:YES];
} else if (segmentedControl.selectedSegmentIndex ==4) {
settingsViewControlle = [[SettingsView alloc] initWithNibName:#"SettingsView" bundle:nil];
[self.navigationController pushViewController:settingsViewControlle animated:YES];
}
}
Any thing else should I mention in this?
You are adding a subview to a segmentedControl. As you don't know how the system redraws the control when another item is selected, you cannot say if your view will be removed or not. Let the control, button or segmentedControl do its work and if you want to add a badge, add it as a subview of its parent.
[surveyCountBadge setFrame:CGRectMake(105.0f+segmentedControl.frame.origin.x,
-10.0f+sementedControl.frame.origin.y, surveyCountBadge.frame.size.width,
surveyCountBadge.frame.size.height)];
[[segmentedControl superView] addSubview: surveyCountBadge];

How to differentiate selected, non selected section on segmented controller

I have used the following code to create a segmented controller, but I can't differentiate which is selected and which is not selected. How do I differentiate?
UISegmentedControl *segmentedControl;
segmentedControl = [[UISegmentedControl alloc] initWithItems:nil];
[segmentedControl insertSegmentWithTitle:#"Male" atIndex:0 animated:YES];
[segmentedControl insertSegmentWithTitle:#"Female" atIndex:1 animated:YES];
segmentedControl.segmentedControlStyle = UISegmentedControlStylePlain;
segmentedControl.frame = CGRectMake(100,10,200,30);
[segmentedControl setMomentary:YES];
[segmentedControl addTarget:self action:#selector(segmentSwitch:) forControlEvents:UIControlEventValueChanged];
- (void)segmentSwitch:(id)sender
{
segmentedControl = (UISegmentedControl *) sender;
NSInteger selectedSegment = segmentedControl.selectedSegmentIndex;
UIView *firstView =[[UIView alloc]initWithFrame:CGRectMake(0, 0, 20,20)];
firstView.backgroundColor=[UIColor greenColor];
UIView *secondView =[[UIView alloc]initWithFrame:CGRectMake(0, 0, 20,20)];
firstView.backgroundColor=[UIColor brownColor];
if (selectedSegment == 0)
{
NSLog(#"first segment");
//toggle the correct view to be visible
strGender =[[NSMutableString alloc]initWithString:#"Male"];
[firstView setHidden:NO];
[secondView setHidden:YES];
}
else
{
NSLog(#"second segment");
//toggle the correct view to be visible
strGender =[[NSMutableString alloc]initWithString:#"Female"];
[firstView setHidden:YES];
[secondView setHidden:NO];
}
}
There are a few things here. Based on your comment to #Surjit's answer, you will have to use insertSegmentWithImage:atIndex:animated if you want to change the color of the segment. You will need to have images for each segment for both selected and non-selected state.
But there are few problems in your segmentSwitch: method. You are creating both firstView and secondView but not adding them to the view hierarchy. You are setting the background color of firstView twice. You probably intended one of the calls to be to secondView. And there's no point changing the hidden property of the two views without them being on the screen. If you are looking to switch between two views of different colors, then declare them as ivars and initialize them elsewhere and then switch their hidden on segment switch.
UISegmentedControl *segmentedControl;
segmentedControl = [[UISegmentedControl alloc] initWithItems:nil];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBezeled;
segmentedControl.frame = CGRectMake(0, 6, 320, 40);
segmentedControl.selectedSegmentIndex = 0;
segmentedControl.tintColor = [UIColor blackColor];
segmentedControl.backgroundColor = [UIColor blackColor];
[segmentedControl setMomentary:YES];
[segmentedControl addTarget:self action:#selector(segmentSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:segmentedControl];
// here is the code how to differenciate selected , non selected section on segmented //controller
int selectedSegment = segmentedControl.selectedSegmentIndex;
if(selectedSegment == 0)
{
// code 1
}
else if(selectedSegment == 1)
{
// code 2
}enter code here
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
UISegmentedControl *segmentedControl; // add this to your (.h) file
segmentedControl = [[UISegmentedControl alloc] initWithItems:nil];
[segmentedControl insertSegmentWithTitle:#"Red" atIndex:0 animated:YES];
[segmentedControl insertSegmentWithTitle:#"Green" atIndex:1 animated:YES];
[segmentedControl insertSegmentWithTitle:#"Blue" atIndex:2 animated:YES];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBezeled;
segmentedControl.frame = CGRectMake(0, 0, 320, 40);
segmentedControl.selectedSegmentIndex = 0;
segmentedControl.tintColor = [UIColor blackColor];
segmentedControl.backgroundColor = [UIColor blackColor];
[segmentedControl setMomentary:NO]; // imp property (change it & see magic)
[segmentedControl addTarget:self action:#selector(segmentSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:segmentedControl];
}
(IBAction)segmentSwitch:(id)sender {
NSInteger selectedSegment = segmentedControl.selectedSegmentIndex;
if (selectedSegment == 0)
self.view.backgroundColor = [UIColor blueColor];
else if (selectedSegment == 1)
self.view.backgroundColor = [UIColor greenColor];
else if (selectedSegment == 2)
self.view.backgroundColor = [UIColor redColor];
}
Just copy & paste this code.
see this example here i am setting tint color for selected
and unselected segment index.
But before that please unchecked the momentary state from xib
for UISegmentedControl.
- (void)segmentAction:(id)sender{
UIColor *tintcolor1=[UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:1.0];
UIColor *tintcolor2=[UIColor colorWithRed:211/255.0 green:78/255.0 blue:65/255.0 alpha:1.0];
for (int i=0; i<[segment_controller.subviews count]; i++)
{
if ([[segment_controller.subviews objectAtIndex:i]isSelected] )
{
[[segment_controller.subviews objectAtIndex:i] setTintColor:tintcolor2];
}else
{
[[segment_controller.subviews objectAtIndex:i] setTintColor:tintcolor1];
}
}

How To Get Values From UISegmentcontroller

I Created Segment Control through Interface Builder.
Created a IBAction and Linked to Value Changed Option of segment Controller.
- (IBAction)GenderBttonAction:(id)sender {
printf("\n Segemt Controll");
}
When i click on segment controller this method is calling , but how would i get the seleced index value of segment controller.
Please help me dears.
((UISegmentedControl *)sender).selectedSegmentIndex;
:-)
I use the following code in a view controller.m to say launch a modal controller and it seems to work good for me.
- (void)viewDidLoad
{
NSArray *segmentContent = [NSArray arrayWithObjects:
NSLocalizedString(#"view 1", #""),
NSLocalizedString(#"view 2", #""),
NSLocalizedString(#"Close", #""),
nil];
//or images insted of text
//NSArray *segmentContent = [NSArray arrayWithObjects:
// [UIImage imageNamed:#"pic.png"],
// [UIImage imageNamed:#"spic.png"],
// [UIImage imageNamed:#"close.png"],
// nil]];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentContent];
segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment;
segmentedControl.momentary = YES; // option
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(0, 0, 160, 30);
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *segments = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segments;
self.navigationItem.title = #"My title";
[segments release];
Then add the actions on selection, last one is a close statement if you launched a modal controller.
- (IBAction)segmentAction:(id)sender
{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
switch ([sender selectedSegmentIndex])
{
case 0:
{
// Do stuff like launch a modal controller. But don't forget to add this all into your modal controller views to get back out :)
InfoViewController *infoViewController = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
UINavigationController *aInfoViewController = [[UINavigationController alloc] initWithRootViewController:infoViewController];
[self presentModalViewController:aInfoViewController animated:YES];
break;
}
case 1:
{
// do stuff
break;
}
case 2:
{
[self.parentViewController dismissModalViewControllerAnimated:YES];
break;
}
}
NSLog(#"Segment clicked: %d", segmentedControl.selectedSegmentIndex);
}
Use the method below if needed to close the modal via this way.
- (IBAction)dismissAction:(id)sender
{
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
and don't forget to declare the action/method in the same respective h file.
- (IBAction)dismissAction:(id)sender;
Hope this helps.
Sincerely, Kirk