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.
Related
I am creating custom dialogs for my app and some what copying UIAlertController in some aspects. How should I implement the behaviour where when you click any action from alert/dialog the controller is dismissed.
How does Apple do it without making us manually specify for each action handler that it should dismiss the view controller?
I have like them one view controller class:
#interface MyAlertViewController : UIViewController
- (void)addAction:(MyAlertAction *) action;
//...
And one class for the actions:
#interface MyAlertAction : NSObject
- (instancetype)initWithTitle:(nullable NSString *)title handler:(void (^)(MyAlertAction *action))handler;
EDIT: How I did it taking in accord the answer feedback:
//MYAlertViewController.m
- (void)viewDidLoad {
for (int i = 0; i < self.actions.count; i++) {
MYAlertAction *action = self.actions[i];
button = [[UIButton alloc] initWithFrame:CGRectZero];
button.tag = i;//this here is how I link the button to the action
[button addTarget:self action:#selector(executeAction:) forControlEvents:UIControlEventTouchUpInside];
[actionStackView addArrangedSubview:button];
[self.actionsStackView addArrangedSubview:actionLayout];
}
}
- (void)executeAction:(UIButton *) sender{
[self dismissViewControllerAnimated:YES completion:^{
//this is where the button tag comes in handy
MYAlertAction *actionToExecute = self.actions[sender.tag];
actionToExecute.actionHandler();
}];
}
How does Apple do it without making us manually specify for each action handler that it should dismiss the view controller?
You are confusing two different things:
The UIAlertAction's last initialization parameter, the handler parameter, which you get to set from outside, and which is to run after the button is tapped and after the alert has been dismissed. It is a block.
The actual button's action, which the client can't set or see. It is configured by the alert controller. It is a selector.
So now, you play the role of the UIAlertController. In your
- (instancetype)initWithTitle:(nullable NSString *)title handler:(void (^)(MyAlertAction *action))handler;
the client hands you the first action I mentioned, the block, and you store it for later execution. But the second action, the button action, the selector, is entirely up to you as you create the button in response to this call.
So as you configure the button, just configure it with a target/action pair that calls into a method of your view controller, just as for any button. In method, when called, the view controller dismisses itself, and in the completion handler of the dismissal, calls the block.
I have a UIButton. I bound a target as follows.
[button addTarget:self action:#selector(myFunction)
forControlEvents:UIControlEventTouchUpInside];
When i click my Button multiple times quickly it invoke the target function multiple times.
On Tapping button i present a new View controller.
when i click 3 times quickly then my new view controller is shown 3 times.
This is something stupid. Whats the point of triggering the function again once the View has been shifted to a new View controller. Why the Hell Apple do such stupid things ?
Any Help please?
First of all its not apple bugs. It should be handle manually. So follow these step
First make your global instance of your button then do this
.h file
#property (weak, nonatomic) IBOutlet UIButton *btn;
.m file
- (IBAction)myFunction:(id)sender
{
self.btn.userInteractionEnabled = NO;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.btn.userInteractionEnabled = YES;
}
Take one global bool flag like "isItDone" or it declare in singleton class.
in "myFunction" set it as false
which View controller you push on that function in that class's "ViewDidAppear" method set as true.
it will help you.
I have same problem and it is good solution for that to manage it using one global variable.
I think this will help you.
Change your calling function like this
- (IBAction)myFunction:(id)sender
{
UIButton *button = (UIButton*)sender;
button.userInteractionEnabled = NO;
}
and call your function like this
[button addTarget:self action:#selector(myFunction:)
forControlEvents:UIControlEventTouchUpInside];
if you want to store the selection incase you came back to the view controller then only you need to keep a boolean flag to store if its clicked once or not.
Set the IBOutlet to your button, in the viewWillAppear method write,
button.userInteractionEnabled = YES;
and when you click on the button set,
button.userInteractionEnabled = NO;
I've hidden a UIView using
_loginview.hidden = YES
and when I do
-(IBaction)logInButton:(id)sender {
_logInView.hidden = NO;
}
It still doesn't show when I click the button, can anyone help?
I have created a Iboutlet property of UIView and connected it with UIView in storyboard. Also ticked hidden.
Screen shot of hidden view is below(color orange). I also sethidden in programmatically way and still working.
And later on button action I perform setHiden as no and it appeared. Code of IBAction is below:-
- (IBAction)loginBtn{
[hidenView setHidden:NO];
}
You need to setHidden NO on your View when you clocked on uiButton..
(IBaction)logInButton:(id)sender{
[_logInView setHidden:NO];
}
It is working my end by creating this,
#property(nonatomic,strong) IBOutlet UIView *viewLogin; // in controller.h
#synthesize viewLogin; // in controller.m
set outlet property for viewlogin in storyboard
and with following IBAction event,
-(IBAction)login:(id)sender{
[viewLogin setHidden:NO]; }
In storyboard, from connections inspector check that your button is connected properly with a sent event.
Then (if you are performing an async process, maybe login user) try this:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
_logInView.hidden = NO;
}];
witch updates the UI from the main thread.
Just a guess.
Better use setAlpha instead of setHidden.
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.
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;