How to check if my button is selected? - ios

If my button is in the "selected" state, I want an activity indicator to appear to let the user know that something is happening and that my app is searching for data. I've tried to accomplish this FIRST by using NSLog to see if I can get this method working FIRST. So I did this:
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}
For some reason, it won't work.

Put this checkmark in your button click event. It perfect work when click on button as first time then got to Not Selected and after click on second time go to Selected.
-(IBAction)ClickBtn:(UIButton *)sender
{
sender.selected = ! sender.selected;
if (sender.selected)
{
NSLog(#" Not Selected");
}
else
{
NSLog(#" Selected");
}
}

try this
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
[searchButton setSelected:YES];
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}

Related

swrevealviewcontrtoller change toggle button image when side menu open/close?

I'm using SWRevealViewContrtoller for slide-out side menu in my app. Which is working fine. But I have an issue, how can I change side-bar button image when button clicked or user dragged side menu. I'm referring to this link.
Thanks in advance
Try to do following-
Method 1 (as per your reference link):
In your homeVC.m set SWRevealViewControllerDelegate like
#interface homeVC ()<SWRevealViewControllerDelegate> and add in viewDidLoad()
self.revealViewController.delegate = self;
then add this method-
-(void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position{
//check position here
if(position == FrontViewPositionLeft) {
[self.sideBarButton setImage:[UIImage imageNamed:#"open.png"] forState:UIControlStateNormal]; //self.sideBarButton is your toggle button IBOutlet
}
else if(position == FrontViewPositionRight) {
[self.sideBarButton setImage:[UIImage imageNamed:#"close.jpg"] forState:UIControlStateNormal];
}
}
Method 2:
In your sideVC.m import-
#import "homeVC.h"
#import "SWRevealViewController.h"
Now add viewWillAppear() and viewWillDisappear()-
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
homeVC *vc=(UserProfileViewController*)self.revealViewController.frontViewController;
[vc.sideBarButton setImage:[UIImage imageNamed:#"close.jpg"] forState:UIControlStateNormal];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
homeVC *vc=(UserProfileViewController*)self.revealViewController.frontViewController;
[vc.sideBarButton setImage:[UIImage imageNamed:#"open.jpg"] forState:UIControlStateNormal];
}
difference between Method1 and Method2 is that, In Method1 when sideVC done animation i.e. position set to FrontViewPositionLeft or FrontViewPositionRight than button image changes by clicking button or dragging view. But in Method2 when sideVC start appearing button image change and when sideVC disappear.
Try FRDLivelyButton. In this library, you can change the UIBarButton image.
Hope it helps.
add <SWRevealViewControllerDelegate>
set self.revealViewController.delegate = self;
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position{
//change button image below.
if(position == FrontViewPositionLeft) {
//drawer close
} else {
//drawer open
}
}
This works for me. Happy coding
UPDATE Swift 3.0
add SWRevealViewControllerDelegate
in your viewDidLoad() add this
self.revealViewController().delegate = self
func revealController(_ revealController: SWRevealViewController!, willMoveTo position: FrontViewPosition) {
if position == FrontViewPosition.left {
//drawer close
}
else {
//drawer open
}
}

Change CPPickerview selection programmatically?

So i have a switch and when it is "on" i would like the CPPickerView to switch to a particular value in an array. As well if the pickerview is moved again i would like the switch to move to the off position.
I know how to get the current day of the week and am trying to switch the pickerview selection to the current day of the week.
If i am way off base here asking such a generalised question just let me know or if you need any more information.
//CPPicker
self.daysOfWeekData = [[NSArray alloc] initWithObjects:#"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday", #"Sunday", nil];
self.dayPickerView.allowSlowDeceleration = YES;
[self.dayPickerView reloadData];
#pragma mark - Horizontal pickerview
//DataSource
-(NSInteger)numberOfItemsInPickerView:(CPPickerView *)pickerView {
return 7;
}
-(NSString *)pickerView:(CPPickerView *)pickerView titleForItem:(NSInteger)item {
return daysOfWeekData[item];
}
//Delegate
-(void)pickerView:(CPPickerView *)pickerView didSelectItem:(NSInteger)item {
self.dayLabel.text = [NSString stringWithFormat:#"%#", daysOfWeekData[item]];
}
//Today's day date
- (IBAction)todaySwitchChange:(id)sender {
if (todaySwitch.on) {
NSLog(#"It is on");
} else {
NSLog(#"It is off");
}
}
This can be done by using CPPickerView's setSelectedItem:animated: method, along with the normal delegate methods.
In your todaySwitchChange: method when the switch is turned on, set the CPPickerView to your desired index:
//Today's day date
- (IBAction)todaySwitchChange:(id)sender {
if (todaySwitch.on) {
NSLog(#"It is on");
// This will cause the CPPickerView to select the item you choose
NSUInteger itemToSelect = someValue; //whatever logic you need to select the right index
[self.dayPickerView setSelectedItem:itemToSelect animated:YES]; // Or disable animation if desired
} else {
NSLog(#"It is off");
}
}
To toggle the switch off when the user scrolls on the CPPickerView, you'll need to hook into the delegate method which gives you notification that scrolling has occurred:
// Implement the following delegate method
- (void)pickerViewWillBeginChangingItem:(CPPickerView *)pickerView {
// Picker is going to change due to user scrolling, so turn the switch off
if (todaySwitch.on) {
todaySwitch.on = NO;
}
}
Hope this helps!

UITextField shouldBeginEditing called every other time?

iOS unfortunately doesn't have a dropdown picker like html does with the tag. I decided that I was finally going to create one for my app, and it looks and works great. My dropdown object is a subclass of UITextField. However, I changed something and now it only works some of the time.
User interaction is enabled, but I don't want the textfield to be editable. The class in which my dropdown subclass resides is UITextField delegate, and should receive delegate methods for UITextField.
I have - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ where I check to see if the textfield in question is a dropdown menu, and if it is, I call a method to instantiate a popover and disable editing, but the dropdown only appears on every other tap.
For example, i'll tap the "textfield" and my popover displays. I tap out so the popover goes away, then I tap on the "textfield" and nothing happens. I tap on the textfield once again and the popover appears. No idea why this is happening, here is what i'm doing:
.h
subclass : UIViewController<UITextFieldDelegate>
.m
dropdownTextField.delegate = self;
...
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if(textField == self.measurementSelect){
NSLog(#"IM CALLED");
[self showPopover:textField];
return NO;
}
return YES;
}
-(void)showPopover:(id)sender{
if (_measurementPicker == nil) {
_measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
_measurementPicker.delegate = self;
}
if (_measurementPopover == nil) {
_measurementPopover = [[UIPopoverController alloc] initWithContentViewController:_measurementPicker];
[_measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
else {
[_measurementPopover dismissPopoverAnimated:YES];
_measurementPopover = nil;
}
}
Every tap gets nslogged, so I assume my popover method is the culprit of this problem. Any ideas?
Let's rewrite by teasing apart existence of the UI elements and the visible state of the popover:
// canonical lazy getters for UI elements
- (iPadMeasurementSelect *)measurementPicker {
if (!_measurementPicker) {
_measurementPicker = [[iPadMeasurementSelect alloc] initWithStyle:UITableViewStylePlain];
_measurementPicker.delegate = self;
}
return _measurementPicker;
}
- (UIPopoverController *)measurementPopover {
if (!_measurementPopover) {
_measurementPopover = [[UIPopoverController alloc] initWithContentViewController:self.measurementPicker];
}
return _measurementPopover;
}
// now the show/hide method makes sense. it can take a bool about whether to show or hide
-(void)showPopover:(BOOL)show {
if (show) {
[self.measurementPopover presentPopoverFromRect:self.measurementSelect.frame inView:self.conversionView permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
} else {
[self.measurementPopover dismissPopoverAnimated:NO];
// if you want/need to create a new one each time it is shown, nil the popover here, like this:
// self.measurementPopover = nil;
}
}
When the textField begins editing, show the popover like this:
[self showPopover:YES];
And when the delegate gets the didEndEditing message:
[self showPopover:NO];

How to implement two IBActions in UIButton without overlap?

I drag 2 IBActions from a UIButton, one with touchDown event and second with drag Inside.
- (IBAction)clickButton:(UIButton *)sender {
NSLog(#"Click Button");
}
- (IBAction)dragInsideButton:(UIButton *)sender {
NSLog(#"Drag Button");
}
But when I drag inside, the touchDown action also gets fired.
How to disable touchDown event when dragInside.
Thanks!
i have solved a problem like this with using drag Events
add events to your button in .xib file or programatically.
programmatically is:
[mybut addTarget:self action:#selector(dragBegan:withEvent: )
forControlEvents: UIControlEventTouchDown];
[mybut addTarget:self action:#selector(dragMoving:withEvent: )
forControlEvents: UIControlEventTouchDragInside];
[mybut addTarget:self action:#selector(dragEnded:withEvent: )
forControlEvents: UIControlEventTouchUpInside |
UIControlEventTouchUpOutside];
then defininitons of events are:
- (void) dragBegan: (UIButton *) c withEvent:ev
{
NSLog(#"dragBegan......");
count=NO;//bool Value to decide the Down Event
c.tag=0;
[self performSelector:#selector(DownSelected:) withObject:mybut afterDelay:0.1];
//user must begin dragging in 0.1 second else touchDownEvent happens
}
- (void) dragMoving: (UIButton *) c withEvent:ev
{
NSLog(#"dragMoving..............");
c.tag++;
}
- (void) dragEnded: (UIButton *) c withEvent:ev
{
NSLog(#"dragEnded..............");
if (c.tag>0 && !count)
{
NSLog(#"make drag events");
}
}
-(void)DownSelected:(UIButton *)c
{
if (c.tag==0) {
NSLog(#"DownEvent");
count=YES;//count made Yes To interrupt drag event
}
}
This method is tested, and should do what I think you're trying to do. You can change the delay in the timer to get the effect you want. I had to connect 3 actions to the button to make this work -- the third action is a touchUp that resets the system to the starting condition.
#interface LastViewController ()
#property (nonatomic) BOOL touchedDown;
#property (strong,nonatomic) NSTimer *downTimer;
#end
#implementation LastViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.touchedDown = NO;
}
-(IBAction)clickDown:(id)sender {
self.downTimer = [NSTimer scheduledTimerWithTimeInterval:.3 target:self selector:#selector(buttonAction:) userInfo:nil repeats:NO];
}
-(IBAction)dragInside:(id)sender {
[self.downTimer invalidate];
[self buttonAction:self];
}
-(void) buttonAction:(id) sender {
if ([sender isKindOfClass:[NSTimer class]]) {
self.touchedDown = YES;
NSLog(#"click down");
}else{
if (! self.touchedDown) {
NSLog(#"Drag");
}
}
}
-(IBAction)touchUpAction:(id)sender {
self.touchedDown = NO;
}
Try this way:
isClicked is property of type BOOL. Set to YES.
- (IBAction)clickButton:(UIButton *)sender { //touch down
if(isClick==YES){
NSLog(#"Click Button");
//do all your stuffs here
}
isClick=YES;
}
- (IBAction)dragInsideButton:(UIButton *)sender {
NSLog(#"Drag Button");
isClick=NO;
}
On top of this you can also implement removeTarget:Action:
Which ever method gets called first set isClick=NO, I expect clickButton is called first in button action.
I got from Two action methods for an UIButton; next track and seek forward:
Change it As per your requirement.
Personally I'd just track the button's state with an integer on your view controller or within a button subclass. If you track what the button is doing you can control what each of the actions do. In your .h file put in some stuff like this:
enum {
MyButtonScanning,
MyButtonStalling,
MyButtonIdle
};
#interface YourClass : UIViewController {
NSInteger buttonModeAt;
}
#property (nonatomic) NSInteger buttonModeAt;
-(IBAction)buttonPushedDown:(id)sender;
-(void)tryScanForward:(id)sender;
-(IBAction)buttonReleasedOutside:(id)sender;
-(IBAction)buttonReleasedInside:(id)sender;
#end
And then in your .m file throw in some of this stuff:
#implementation YourClass
///in your .m file
#synthesize buttonModeAt;
///link this to your button's touch down
-(IBAction)buttonPushedDown:(id)sender {
buttonModeAt = MyButtonStalling;
[self performSelector:#selector(tryScanForward:) withObject:nil afterDelay:1.0];
}
-(void)tryScanForward:(id)sender {
if (buttonModeAt == MyButtonStalling) {
///the button was not released so let's start scanning
buttonModeAt = MyButtonScanning;
////your actual scanning code or a call to it can go here
[self startScanForward];
}
}
////you will link this to the button's touch up outside
-(IBAction)buttonReleasedOutside:(id)sender {
if (buttonModeAt == MyButtonScanning) {
///they released the button and stopped scanning forward
[self stopScanForward];
} else if (buttonModeAt == MyButtonStalling) {
///they released the button before the delay period finished
///but it was outside, so we do nothing
}
self.buttonModeAt = MyButtonIdle;
}
////you will link this to the button's touch up inside
-(IBAction)buttonReleasedInside:(id)sender {
if (buttonModeAt == MyButtonScanning) {
///they released the button and stopped scanning forward
[self stopScanForward];
} else if (buttonModeAt == MyButtonStalling) {
///they released the button before the delay period finished so we skip forward
[self skipForward];
}
self.buttonModeAt = MyButtonIdle;
}
After that just link the button's actions to what I've noted in the comments before the IBactions. I haven't tested this but it should work.
i'm not sure it will work but you can try
- (IBAction)dragInsideButton:(UIButton *)sender {
[sender removeTarget:self forSelector:#selector(clickButton:) forControlEvent:UIControlEventTouchDown];
}

Check which UIButton was Clicked from another function

In my xib I have taken 4 UIbuttons named button 1, 2, 3 and 4. These four buttons are connected two four different IBAction methods which perform different functions.
Now I have one more button called "Save" This has also a different IBAction method.
- (IBAction)Save:(id)sender
{
}
Now here I want to check which of the above 4 UIButtons have been clicked.
For this I tried checking this way
- (IBAction)Save:(id)sender
{
if(sender == button1)
{
//Do this
}
else if (sender == button2)
{
//Do this
}
}
But this is not working. I am doing something wrong.Please help me out
Regards
Ranjit.
You can set the tag values for each button in the interface builder and set actions of all buttons to this method
//set global variable flag.
int flag;
- (IBAction)buttonClicked:(id)sender
{
switch ([sender tag])
{
case 0:
{
flag =0;
// implement action for first button
}
break;
case 1:
{
flag =1;
// implement action for second button
}
break;
case 2:
{
flag =2;
// implement action for third button
}
break;
//so on
default:
break;
}
}
for save button
- (IBAction)save:(id)sender
{
switch (flag)
{
case 0:
{
// first button clicked
}
break;
case 1:
{
// second button clicked
}
break;
case 2:
{
// third button clicked
}
break;
//so on
default:
break;
}
}
Define a class level ivar as
UIButton *selectedBtn;
Then in you IBActions
- (IBAction)button1:(id)sender {
selectedBtn = sender // or button1
}
- (IBAction)button2:(id)sender {
selectedBtn = sender // or button2
}
- (IBAction)button3:(id)sender {
selectedBtn = sender // or button3
}
- (IBAction)button4:(id)sender {
selectedBtn = sender // or button4
}
- (IBAction)Save:(id)sender
{
//Check output of below statement to ensure you're getting a sender
NSLog(#"Sender: %#", sender);
if(selectedBtn == button1)
{
NSLog(#"Button 1 pressed");
//Do this
}
else if (selectedBtn == button2)
{
NSLog(#"Button 2 pressed");
//Do this
}
else if (selectedBtn == button3)
{
NSLog(#"Button 3 pressed");
//Do this
}
else if (selectedBtn == button4)
{
NSLog(#"Button 4 pressed");
//Do this
}
}
Can you try this:
- (IBAction)Save:(id)sender
{
UIButton *pressedButton = (UIButton*)sender;
//Check output of below statement to ensure you're getting a sender
NSLog(#"Sender: %#", sender);
if([pressedButton isEqual:button1])
{
NSLog(#"Button 1 pressed");
//Do this
}
else if ([pressedButton isEqual:button2])
{
NSLog(#"Button 2 pressed");
//Do this
}
}
In your save method, check the Selected property of the other 4 buttons. If you do not want to keep the buttons in a selected state, but just want to see if they were clicked at some point, then define a property (e.g. an array) to track which buttons were clicked during the session, and check this property in your save method.

Resources