Is there a way to cancel a touch for a UIButton? I envision it as something like:
- (BOOL)shouldProcessTouch {
return NO;
}
You know, a place where you can run logic and cancel the touch in certain scenarios. Any ideas?
** EDIT **
For those familiar with event based systems, I'm looking for the equivalent of:
event.stopPropagation();
In most cases, a UIButton will call a method when touched. It may look like this:
-(IBAction)submitButtonPressed:(id)sender{
if(shouldRespond){
//do things normally
}
else{
return; //do nothing
}
}
In this example, shouldRespond is your flag. You should set this flag based on whatever conditions you have.
edit: the flag is a BOOL
Why not just putting button in disabled state?
button.enabled = NO;
Or, disable user interaction for it:
button.userInterationEnabled = NO;
Related
When the accessibility option is turned on the device, we're not able to turn off the closed caption by setting the closedCaptionEnabled option for the AVPlayer instance as we normally would. Is there a way to bypass such option or even to test if it's enabled to lock the CC button if necessary?
You can iterate through each AVPlayerItemTrack and enable/disable it as you wish.
This is how I do in one of my project. I show table of available CC tracks and when the user selects one I iterate through each track, enable the on that user selected and disable rest.
//_selectedTrackIndex = userSelectedIndex;
-(void) setSelectedTrackEnabled {
for (AVPlayerItemTrack * t in [_playerItem tracks]) {
if (counter == _selectedTrackIndex) {
[t setEnabled:YES];
} else {
[t setEnabled:NO];
}
}
}
Sometimes when user go back to the previous UIViewController, I want to do something.
If the user clicked the back button in UINavigationBar, I can capture the event.
But if they use the swipe back gesture to go back, I cannot respond to the change.
So is there any callback for swipe back gesture?
Currently I can only disable this kind of page in my app through
interactivePopGestureRecognizer.enabled = NO;
The easiest way is to hook into the one that's already built into UINavigationController by doing something like this:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.addTarget(self, action: #selector(MyViewController.handleBackswipe))
}
#objc private func handleBackswipe() {
navigationController?.interactivePopGestureRecognizer?.removeTarget(self, action: #selector(MyViewController.handleBackswipe))
// insert your custom code here
}
The remember to call removeTarget(_:action:) in your selector, otherwise it'll spam your selector until the gesture ends.
Try this.It gives you some what better solution.
- (void)viewDidLoad {
[super viewDidLoad];
UIScreenEdgePanGestureRecognizer *gesture = (UIScreenEdgePanGestureRecognizer*)[self.navigationController.view.gestureRecognizers objectAtIndex:0];
[gesture addTarget:self action:#selector(moved:)];
}
In Target method.
-(void)moved:(id)sender{
// do what you want
//finally remove the target
[[self.navigationController.view.gestureRecognizers objectAtIndex:0] removeTarget:self action:#selector(moved:)];
}
As the question states, is it possible to disable userInteracion within a UICollectionViewCell?
I know the code is to disable the view would be: self.view.userInteractionEnabled = NO; in the .m file.
I have a button inside a Cell and I'm wondering if during the action of this button I could disable the entire View until the action is done (action: saving an image).
Any thoughts would be appreciated!
Note: Cell has its own class. Inside the button with its action method.
Base on your description, the saving action is asynchronous, so you can insert self.view.userInteractionEnable = NO to the top selector of the button's touch event. and resume it after the saving.
- (void)onButtonClick:(UIButton *)button{
//self.view.userInteractionEnable = NO;
self.userInteractionEnable = NO;
/* start saving the image */
}
//here maybe the callback for your saving
- (void)savingImageFinished{
//self.view.userInteractionEnable = YES;
self.userInteractionEnable = YES;
}
You can use a block with a completion handler for the button action. Disable the userInteraction within the block code and in the completion handler add self.view.userInteractionEnabled = YES to reenable it.
In my small app, user clicks on "ON" button then I call a method with a while loop and "OFF" button should appear, however my "OFF" button does not show up.
-(void) myMethod{
while (_onButton.selected) {
[self vibrate];
NSLog(#"working");
}
}
- (IBAction)on:(id)sender {
_offButton.hidden=NO;
_offButton.selected=NO;
_onButton.hidden=YES;
_onButton.selected=YES;
[self myMethod];
}
- (IBAction)off:(id)sender {
_onButton.hidden=NO;
_offButton.hidden=YES;
_onButton.selected=NO;
_offButton.selected=YES;
}
As you are using this loop:
while (_onButton.selected) {
[self vibrate];
NSLog(#"working");
}
You aren't allowing the runloop to process new events, and so the button will never have the opportunity to change state (as it won't receive touches from the user). This is very bad and you shouldn't do this.
Instead continue your vibration by using a sound delegate method that continues all the time the button is selected (you don't show how you perform your vibration, so I cannot give more detail here).
EDIT After comment from OP:
- (void)vibrate
{
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
OK, AudioServices provides a "completion procedure" via AudioServicesAddSystemSoundCompletion() which will allow you to replay the vibration "sound" all the time the button is selected. Use this mechanism rather than the while loop.
It's an infinite loop mate. change the while loop like this:
while (_onButton.selected) {
[self vibrate];
NSLog(#"working");
_onButton.selected = NO;
}
or
while (_onButton.selected) {
[self vibrate];
NSLog(#"working");
break;
}
essentially I'm deleting pictures inside of an app.. everything is coded etc.. etc.. so when the user holds the UIButton the image is swapped and has the X over it. Click again and image is deleted from the Doc Directory and DB. So it only made sense to add an alertview before deletion.. problem is that the methods I'm using use (UIButton*)sender as a parameter. I need to pass that parameter to the next method to property delete from the screen.
Is there a relatively simple way to do this..
this is the function that calls the deletion.. the function that would initiate the alertview is also returns a void and takes the same UIButton.
-(void)action:(UIButton*)sender {
if (edit == true)
{
[sender removeFromSuperview];
[[scrollView viewWithTag:[sender tag]] removeFromSuperview];
[self deleteFromDoc:sender];
edit = false;
stop = false;
NSLog(#"remove");
}
}
Change your method to
-(void)action:(UIView *)sender
Assign the tag of the uibutton to the alertview, then in didClickButtonWithIndex: call your action: method passing in the alertView as sender.