touch any where on screen to activate method - iphone

I have an if statement that is bringing up a SVProgressHUD that lets the user know there is an error. I would like to create a touch event programmatically but I am not sure how to define my view when I am using a tableview which was set up in interface builder
this is the code I would like to use
[myView addTarget:self action:#selector(myAction:)forControlEvents:UIControlEventTouchUpInside];
but I am not sure how to create myView when I am using a tableview. What is the best way to handle this?

You can add a UIButton with transparent color and add it to your view.
Then you'll be able to use the following method:
[myButton addTarget:self action:#selector(myAction:)forControlEvents:UIControlEventTouchUpInside];

Add tapGestureRecognizer to the view with target and event to handle the tap event such that when a user click or touches the view it triggers the selector.
UIGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(mySelector:)]
[myView addGestureRecognizer: recognizer];
Then you could add the selector which simply takes the recognizer as the sender;
-(void)mySelector:(UIGestureRecognizer*)gr{
// handling event
}

Related

UIView addSubView with animation, but allow the old underlying tap

I have a UIView myView that responds to user taps.
I have added an animated view using:
[myView addSubView:animatedView];
But now the animated view, is blocking the taps, Since both use the same frame
How can I override that easily?
The best way I can see to you to do that is you declare the UITouchGesture in your views, and when you need to disable the touch in the view you can disable:
An example for a tap:
In your .h file you declare it:
UITapGestureRecognizer* tap;
And in your .m file
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[yourView addGestureRecognizer:tap];
And when you need to disable the tap you can simple:
[tap setEnable:NO];
or remove it:
[yourView removeGestureRecognizer:tap];
With that when you need to enable/disable will be easier and also will be easier to you to manage your touchs.

how to know uitableview is pressed when empty

i am making a chat application, and in the chat window there are uilabels in uitableviewcells. initially the keyboard will be present but when the user touches on any place on uitableview, i will make the chat window as fullscreen (dissappearing keyboard).
i cant find a way/trick to accomplish this.
i have tried the following method: by using tableview:didselectrowatindexpath, i am able to do it but, user needs to press on an existent uitableviewcell. but i want to understand the press even when uitableview is empty..
note: my chat tableview is interactive e.x. some rows will include image button which need to be pressable, so i cant just put an invisible button onto uitableview.
thank you for your thoughts
Aytunc Isseven
What you want to do is add a gesture recognizer to the UITableView that responds to the appropriate gestures. I would recommend against using UITapGestureRecognizer as the UITableView is already using taps for selecting the cells, so you might want to try the UILongPressGestureRecognizer. I put together a small sample of how you can do this as follows:
In my viewDidLoad I did the following:
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressFrom:)];
[self.tableView addGestureRecognizer:gesture];
and the handleLongPressFrom: is as follows:
- (void)handleLongPressFrom:(UILongPressGestureRecognizer *)recognizer {
NSLog(#"handleLongPressFrom: %#", recognizer);
// Add real code here
}
The full list of gestures can be found here.
Oh, if you did want to still use tap, check out this stack overflow question. I don't know if the method presented works fully, but it'd be a good place to start.
Using UITapGestureRecognizer with a UITableView:
Okay, since the tap gesture seems to be the correct one for your use case you can try and do the following. Step 1 is to set up the gesture recognizer as I listed above using the tap gesture instead of the long press gesture.
The code in viewDidLoad is very similar with an important addition ...
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFrom:)];
// we need to set the gesture delegate so we can allow the tap to pass through to the
// UITableViewCell if necessary.
gesture.delegate = self;
[self.tableView addGestureRecognizer:gesture];
The handleTapFrom: function is pretty much the same with just the different gesture recognizer as the parameter.
- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer {
NSLog(#"handleTapFrom: %#", recognizer);
// Add real code here
}
The major changes to this approach is that we need to implement the UIGestureRecognizerDelegate protocol. Since our goal is to allow the tap gesture to pass through the UITableView to it's subviews (i.e. the UITableViewCell and it's components) we need to implement the gestureRecognizer:shouldRecieveTouch: function. The following implementation should cover what you are attempting.
#pragma mark UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// If the view that is touched is not the view associated with this view's table view, but
// is one of the sub-views, we should not recognize the touch.
if (touch.view != self.tableView && [touch.view isDescendantOfView:self.tableView]) {
return NO;
}
return YES;
}
The isDescendantOfView: function returns YES if the view it is testing against is the same as the view doing the testing, so we need to accommodate that case separately. You can generify this function by using gestureRecognizer.view instead of self.tableView, but I didn't think it was necessary in this case.
The trick is to make your viewController put a tap recognizer on the view but make it always opt out by returning NO from the delegate method "gestureRecognizerShouldBegin". That way gestureRecognizerShouldBegin gets called for every touch on the view, but you don't interfere with the normal event handling of the table.
- (void)viewDidLoad {
[super viewDidLoad];
[self detectTouchesOnView:self.tableView];
}
- (void)detectTouchesOnView:(UIView*)theView {
UITapGestureRecognizer* tapR = [[UITapGestureRecognizer alloc]initWithTarget:nil action:nil];
tapR.delegate = self;
[theView addGestureRecognizer:tapR];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
// React to the UITableView being touched E.G. by hiding the keyboard as below.
[self.view endEditing:YES];
return NO;
}

How to trigger a hidden UIButton's event in the action of a UIBarButtonItem

I have a UIButton, which is placed over a UINavigationBar's rightBarButtonItem. The UIButton is hidden. So in the view only the UINavigationBar's rightBarButtonItem is visible. On the click of the rightbarbuttonitem, I want to trigger the action of the hidden UIButton. Is it possible. If so, how?
Edit: Is there any way to do this without using selectors. Is there a way like where I can just trigger the UIButton action on the click of the UIBarButtonItem, like action:UIButton.action
Please try the below code to trigger the action for UIBarButtonItem. But you have tu use selector in this!!!
- (void) viewDidLoad
{
// change the back button and add an event handler
self.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"Pages"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(handleBack:)];
}
- (void) handleBack:(id)sender
{
// do your custom handler code here
// make sure you do this!
// trigger an hidden button
[itsHiddenButton sendActionsForControlEvents: UIControlEventTouchUpInside];
}
. Hope this helps..
The method called when rightBarButtonItem is touched can be called when UIButton is touched.
-(IBAction)rightBarButtonTrigger:(id)sender {
NSLog(#"rightBarButtonTrigger");
[self uiButtonTrigger:sender];
}
-(IBAction)uiButtonTrigger:(id)sender {
NSLog(#"uiButtonTrigger");
}
You can write a common method for your both buttons rightBarButtonItem and UIButton. So they will fire the same method on its click event.

Override UITextView's UIScrollView Method touchEnded

I've a UITextView (from the InterfaceBuilder) in my View. This contains a UIScrollView.
Now I have to detect touch Events inside the UITextView beacause I must close my own submenus.
The Apple UITextView is in a UIScrollView, and to detect a touch in a UIScrollView I've to ovveride the UITouch Funktion of UITextView's UIScrollView.
Any suggestions how I can do this?
UITextView is a subclass of UIScrollView. Is this what you mean when you say "contains a UIScrollView?"
There are a couple of approaches you could take here. If the touch you are concerned with is the first touch in the text view, and is therefore beginning editing, you can become its delegate and implement this method:
- (void)textViewDidBeginEditing:(UITextView *)textView
If you need to be aware of any tap that occurs inside the text view, not just initial editing taps, you can use a UITapGestureRecognizer to listen for taps. Something like this:
// in the method where you configure your view
UITapGestureRecognizer *tap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(textViewTapped:)] autorelease];
// assuming textView is pointing to your UITextView
[textView addGestureRecognizer:tap];
And then implement the action method elsewhere in your class:
- (void)textViewTapped:(id)sender {
// dismiss your menu or whatever
}
Note that I haven't actually tested this scenario, but it should work. Gesture recognizers are awesome.

Is it possible to receive UITapGestureRecognizer calls in 2 classes at the same time

I want to call an action in two classes (a superview and a full screen subview) when the user single taps the screen. But, when I add a UITapGestureRecognizer to the subview, the one added to the superview is overridden. Is it possible to add a UITapGestureRecognizer to a subview without overriding the UITapGestureRecognizer added to the superview?
If so, how can I do this?
Thanks!
Edit:
From my main viewController "MyToolBerController", I'm adding the subview from another viewController as follows:
PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
myPhotoView = photoViewController.view;
[self.view addSubview:myPhotoView];
I add the GestureRecognizer in the MyToolBerController like this:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTapFrom:)];
[singleTap setNumberOfTapsRequired:1];
singleTap.delegate = self;
[myPhotoView addGestureRecognizer:singleTap];
[singleTap release];
This all works fine, but I need to call a method in the PhotoViewController class when the view is tapped as well as in the MyToolBerController class.
When I add another UITapGestureRecognizer in the photoViewController, it overrides the UITapGestureRecognizer added in the superView.
Gesture recognizers can dispatch multiple actions when the gesture occurs. You can add the subview as another target of the gesture recognizer and only use a single UITapGestureRecognizer instance:
[tapRecognizer addTarget:theSubview action:#selector(whatever:)];
In your gesture recognizer selector method, pass the information along to the subview. There's no need to have multiple gesture recognizers for the same gesture. Something like:
- (IBAction)handleSingleDoubleTap:(UIGestureRecognizer *)sender
{
CGPoint tapPoint = [sender locationInView:sender.view.superview];
UIView *subview = [parentView viewWithTag:100];
[subview doSomethingWithPoint:tapPoint];
}
This of course means that your subview that needs to be notified should be given the tag 100 either in Interface Builder or in code when the view controller gets loaded.
Update based on Jonah's code:
So instead of retaining the view, retain the view controller:
PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
self.myPhotoViewController = photoViewController;
Which means you need to declare it this way in the MyToolbarController header:
#property (nonatomic, retain) PhotoViewController *myPhotoViewController;
Then, when your gesture selector gets called, pass the message along to the view controller you retained. Something like:
- (IBAction)handleSingleTapFrom:(UIGestureRecognizer *)sender
{
CGPoint tapPoint = [sender locationInView:sender.view.superview];
[myPhotoViewController doSomethingWithPoint:tapPoint];
}
Of course the -doSomethingWithPoint: method is only for example. You can name and create any method you want that takes any parameter you want to pass in your PhotoViewController.
Let me know if you need further clarification.