There are few answers on SO (UILongPressGestureRecognizer), but I'm unable to get the correct value with the following code, not sure what I'm doing wrong. Tried few more pages on SO and similar one more third party website tutorial but unable to get the exact button detail.
#property (nonatomic,strong) UILongPressGestureRecognizer *lpgr;
#property (strong, nonatomic) IBOutlet UIButton *button1;
#property (strong, nonatomic) IBOutlet UIButton *button2;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGestures:)];
self.lpgr.minimumPressDuration = 2.0f;
self.lpgr.allowableMovement = 100.0f;
[self.view addGestureRecognizer:self.lpgr];
}
- (void)handleLongPressGestures:(UILongPressGestureRecognizer *)gesture
{
if ([gesture isEqual:self.lpgr]) {
if (gesture.state == UIGestureRecognizerStateBegan)
{
if (gesture.view == self.button1) {
NSLog(#"Button 1 is pressed for long");
}else if(gesture.view == self.button2) {
NSLog(#"Button 2 is pressed for long");
}else{
NSLog(#"another UI element is pressed for long");
}
}
}
}
Every time button is press for long, I'm getting NSLog(#"another UI element is pressed for long");
The else statement is being hit every time because you are adding the gesture to the main view. Even when you are long pressing on the button the event is being passed up to the view where you are catching it. If you add the lines below in viewDidLoad it will fire on the buttons appropriately.
[self.button1 addGestureRecognizer:self.lpgr];
[self.button2 addGestureRecognizer:self.lpgr];
You have added gestures to self.view instead of button1/button2.
Related
i Am using Mb Progress Bar. in which the progress bar is sccessing automatically. here i want to move the progress bar with my mouse cursor.
i am using Github Library
https://github.com/matibot/MBCircularProgressBar
This library gives me animated progress bar which runs automatically on button click. i want exactly this one. but it should not be automatically. i want to move it by my cursor like hand moment.
this is my code:::
#property (weak, nonatomic) IBOutlet MBCircularProgressBarView *progressBar;
#property (weak, nonatomic) IBOutlet UISwitch *animatedSwitch;
#end
#implementation MBViewController
- (void)viewDidLoad {
[super viewDidLoad];
// pan gesture detects circle dragging
UIPanGestureRecognizer *pv = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
//[self addGestureRecognizer:pv];
[self.progressBar addGestureRecognizer:pv];
}
- (IBAction)animate:(UIButton *)sender {
[UIView animateWithDuration:self.animatedSwitch.on * 1.f animations:^{
self.progressBar.value = 100.f - self.progressBar.value;
}];
}
# pragma mark detect pan and determine angle of pan location vs. center of circular revolution
- (void) handlePan:(UIPanGestureRecognizer *)pv {
self.progressBar.value = 100.f - self.progressBar.value;
}
Anyone can have idea. please help me for this::
I have a UITableViewController with an xib that is being used in a popover. It was working fine until I tried to add a UITapGestureRecognizer to the view. With the tableview wired to the UITapGestureRecognizer as an outlet collection, when the user taps an item in the table, the tap handler fires but the didSelectRowAtIndexPath method of the tableview no longer fires.
What I am trying to do is get the position of the tap so I can throw the next popover up in a reasonable location. Maybe there is a better way to do this?
Heres is what my tableview wiring looks like...
Here is the wiring for the recognizer...
Here is my tap handler, which when wired up, fires fine when the user selects an item.
- (IBAction)tapHandler:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
tapPosition = [sender locationInView:self.view];
}
}
Here is the didselectrowAtIndexPath method. Fires fine unless I wire up the tapGestureRecognizer...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[myPO dismissPopoverAnimated:YES];
[self.delegate popupListItemSelected:self withItemRow:indexPath.row item:[listItems objectAtIndex:indexPath.row]];
}
Here is the applicable part of my interface file. All of the objects are synthesized...
#import <UIKit/UIKit.h>
#protocol PopUpListViewControllerDelegate;
#interface PopUpListViewController : UITableViewController {
id<PopUpListViewControllerDelegate> delegate;
IBOutlet UITableView *poupListTableView;
UIPopoverController *myPO;
NSMutableArray *listItems;
IBOutlet UITapGestureRecognizer *tapRecognizer;
}
#property (assign) id<PopUpListViewControllerDelegate> delegate;
#property (retain, nonatomic) IBOutlet UITableView *poupListTableView;
#property (retain, nonatomic) NSMutableArray *listItems;
#property (retain, nonatomic) IBOutlet UITapGestureRecognizer *tapRecognizer;
- (IBAction)tapHandler:(UITapGestureRecognizer *)sender;
- (CGPoint)getTappedPosition;
#end
One option might be to use the CGPoint from your tap handler and find the corresponding row using the UITableView method:
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;
So, everything could potentially be handled by your tapHandler: (warning! untested pseudo-code!)
- (IBAction)tapHandler:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
tapPosition = [sender locationInView:self.view];
// use the appropriate name for your tableView, of course.
CGPoint pointInTable = [sender locationInView:self.tableView];
NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint:pointInTable];
[myPO dismissPopoverAnimated:YES];
[self.delegate popupListItemSelected:self withItemRow:indexPath.row item:[listItems objectAtIndex:indexPath.row]];
}
}
i have my button, created from storyboard:
#property (weak, nonatomic) IBOutlet UIButton *plusOneBtnPoisonTwo;
with its method:
- (IBAction)plusOnePlayerTwoPoison:(id)sender;
then I check device rotation and set new position:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// NSLog(#"%d", toInterfaceOrientation);
if(!UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
self.plusOneBtnPoisonTwo.center = CGPointMake(284, 406);
}
}
the button moves in the new position, but the method plusOnePlayerTwoPoison is no more triggered...
Any Idea?
Thanks.
Try using this instead. Its just a guess that it may resolve your problem.
#property (retain, nonatomic) IBOutlet UIButton *plusOneBtnPoisonTwo; //change to retain
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//add button action manually by code
[plusOneBtnPoisonTwo addTarget:self action:#selector(plusOnePlayerTwoPoison:) forControlEvents:UIControlEventTouchDown];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// NSLog(#"%d", toInterfaceOrientation);
if(!UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
[plusOneBtnPoisonTwo setFrame:CGRectMake(284, 406,50,100)];
}
}
I have UITextFields in tableviewcells. When you swipe over the cell not part of the textfield, the delete action comes up as expected. If you swipe over the textfield, it stops the delete from popping up.
How do I fix this so that you can swipe over the inputs and the cell will trigger the delete action?
I think the issue here is that the touch on the text field is interfering with your swipe gesture recognizer (presumably attached to the parent view). I had a similar problem with a text field that was placed in a UIScrollView.
I got around this problem by overlaying a clear UIView on top of my UITextField. I then assigned a UITapGestureRecognizer to this clear view to set the text field as the first responder when the user taps on the field. Otherwise, the swiped is sent to the parent view (a scroll view) which recognizes the swipe without any issues. It's kind of lame but it works.
This scenario is a bit different from yours, but I think it's the same problem. Here is what my code looks like, hopefully it helps:
// UIView subclass header
#interface LSAddPageView : UIView
#property (weak, nonatomic) IBOutlet UITextField *textField; // Connected to the UITextField in question
#property (strong, nonatomic) UIView *textFieldMask;
#property (assign, nonatomic) BOOL textFieldMaskEnabled;
#end
// UIView subclass implementation
#implementation LSAddPageView
- (void)awakeFromNib
{
[super awakeFromNib];
_textFieldMask = [UIView new];
_textFieldMask.backgroundColor = [UIColor clearColor];
[self insertSubview:_textFieldMask aboveSubview:self.textField];
}
- (void)layoutSubviews
{
[super layoutSubviews];
_textFieldMask.frame = self.textField.frame;
}
- (BOOL)textFieldMaskEnabled
{
return _textFieldMask.hidden == NO;
}
- (void)setTextFieldMaskEnabled:(BOOL)textFieldMaskEnabled
{
_textFieldMask.hidden = !textFieldMaskEnabled;
}
#end
And then in the controller:
- (void)viewDidLoad
{
[super viewDidLoad];
_addPageView = (LSAddPageView*)self.view;
_maskGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didTapMask:)];
_maskGestureRecognizer.numberOfTapsRequired = 1;
_maskGestureRecognizer.numberOfTouchesRequired = 1;
[_addPageView.textFieldMask addGestureRecognizer:_maskGestureRecognizer];
self.textField.delegate = self; // Set delegate to be notified when text field resigns first responder
}
- (void)didTapMask:(UIGestureRecognizer*)recognizer
{
_addPageView.textFieldMaskEnabled = NO;
[self.textField becomeFirstResponder];
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
_addPageView.textFieldMaskEnabled = YES;
return YES;
}
Sounds like you need to set the cancelsTouchesInView property
yourGestureRecognizer.cancelsTouchesInView = NO;
from UIButton & UITextField will block UITableViewCell being swipe to delete
self.tableView.panGestureRecognizer.delaysTouchesBegan = YES;
this will make the textfield not stop left swipe guestures
First my .h file:
#interface SettingsViewController : UIViewController <UINavigationControllerDelegate>
{
IBOutlet UISwitch *gravaSwitch;
...
}
#property (retain, nonatomic) UISwitch *gravaSwitch;
...
#end
My viewDidload in .m file (it works):
...
// SET SWITCH BUTTON STATE
keychain = [[KeychainItemWrapper alloc] initWithIdentifier:#"TrafficApp" accessGroup:nil];
if ( [[keychain objectForKey:(id)kSecAttrAccount] isEqualToString:#"" ] )
[self.gravaSwitch setOn:FALSE];
else [self.gravaSwitch setOn:TRUE];
...
But my switchChanged doesn't work and I don't know why. On IB everything is right connected, it enters in this method but gravaSwitch is always null.
- (IBAction)switchChanged:(id)sender
{
if ( self.gravaSwitch.on )
{
NSLog(#"IF");
[self.gravaSwitch setOn:FALSE animated:YES];
}
else
{
NSLog(#"ELSE");
[self.gravaSwitch setOn:TRUE animated:YES];
}
}
Regards.
I think the error is the following:
#interface SettingsViewController : UIViewController <UINavigationControllerDelegate>
{
UISwitch *gravaSwitch;
...
}
#property (retain, nonatomic) IBOutlet UISwitch *gravaSwitch;
...
#end
IBOutlet placeholder has to be inserted into #property. Change your code and try to connect your outlet again.
Edit:
Try to create your UISwitch programatically. Change your #property as the following:
#property (retain, nonatomic) UISwitch *gravaSwitch;
Leave #synthesize as is. Then in your viewDidLoad method add your UISwitch (by default on property is FALSE):
// Width and height are set to zero but they take the default dimension
UISwitch *yourSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 0, 0)];
// add target and action
mySwitch addTarget:self action:#selector(yourCustomAction:) forControlEvents:UIControlEventValueChanged];
self.gravaSwitch = yourSwitch;
// don't forget because gravaSwitch has already a retain policy
[release yourSwitch];
// add the switch to the view
[self.view addSubview:self.gravaSwitch];
Within the same controller, but outside the viewDidLoad method, add the following method:
- (void)yourCustomAction:(id)sender
{
if ( self.gravaSwitch.on )
{
NSLog(#"IF");
[self.gravaSwitch setOn:FALSE animated:YES];
}
else
{
NSLog(#"ELSE");
[self.gravaSwitch setOn:TRUE animated:YES];
}
}
- (void)dealloc
{
self.gravaSwitch = nil; // remember to dealloc the switch!!
[super dealloc]
}
You could call self.gravaSwitch = nil; also in viewDidUnload method.
As an alternative you can set gravaSwicth to assign policy as follow. In this case you haven't to call self.gravaSwitch = nil; both in dealloc and/or viewDidUnload.
#property (assign, nonatomic) UISwitch *gravaSwitch;
Hope it helps.
Edit 2:
This code works for me. This is the implementation (.m file) for MyViewController.
#synthesize gravaSwitch;
- (void)viewDidLoad
{
[super viewDidLoad];
UISwitch *yourSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 0, 0)];
[yourSwitch addTarget:self action:#selector(yourCustomAction:) forControlEvents:UIControlEventValueChanged];
self.gravaSwitch = yourSwitch;
[yourSwitch release];
[self.view addSubview:self.gravaSwitch];
}
- (void)yourCustomAction:(id)sender
{
if(self.gravaSwitch.on)
{
NSLog(#"on");
}
else
{
NSLog(#"off");
}
}
where gravaSwicth is declared within MyViewController.h as follows:
#interface MyViewController : UIViewController
{
UISwitch *gravaSwitch;
...
}
#property (retain, nonatomic) UISwitch *gravaSwitch;
...
#end
rembember to call self.gravaSwicth = nil in dealloc in MyViewController.m!!
FWIW I had this problem when my UISwitch was in a UITableViewCell, and I put it at the top of the list of subviews in Interface Builder (and therefore beneath the other views in the cell when running). It worked in a develop build but not a production build for who knows what reason. In prod, I would click on the UISwitch and the whole row would blink ask if selected.
So I moved it to the bottom of the list (and therefore above the other views in the cell when running) and then I could click on the UISwitch.
-(IBAction)alarmSwitchToggled:(id)sender
{
if ([switchAlarm isOn]) {
NSLog(#"switch is ON");
}
else
{
NSLog(#"switch is OFF");
}
}
Give proper connections in nib file and dont forget to make it as valuechanged instead of touchupinside