How hide cell wile reordering TableVirew - ios

Aim is to hide cell which is reordering when reordering animation starts and show cell when reordering animation stops.
PS
When you moving cell, it's alpha is changed, i think there is a way to set alpha to 0, but how? It is necessary for me to hide else shadow of moving cell, because i try show diferent picture instead moving cell.

[yourtableviewcell setHidden:YES];
If you want to fade it away, animate the alpha to 0 first.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
yourtableviewcell.alpha = 0;
[UIView commitAnimations];

There answer to shadow question

I used next code in my CustomCell class and result is in the picture. Cell is hidden and it's good.
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSLog(#"Drugging"); // Dragging started
self.hidden=YES;
} else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"Drugging End"); // Dragging ended
self.hidden=NO;
}
}
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *view in self.subviews) {
if ([NSStringFromClass ([view class]) rangeOfString:#"ReorderControl"].location != NSNotFound) { // UITableViewCellReorderControl
if (view.gestureRecognizers.count == 0) {
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
gesture.cancelsTouchesInView = NO;
gesture.minimumPressDuration = 0.150;
[view addGestureRecognizer:gesture];
}
}
}
}

Related

UITapGestureRecognizer for detecting which UIView was tapped on my screen

I am using UITapGestureRecognizer for detecting which UIView was tapped on my screen but for some reason it only detects the parent view tap, for example below code logs only parent views tag. How do i detect subview taps which are present on main view. Please suggest.
Inside View did load :-
UITapGestureRecognizer *viewTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(actionForViewTapped:)];
[self.view addGestureRecognizer:viewTapRecognizer];
-(void) actionForViewTapped:(UITapGestureRecognizer*)sender {
NSLog(#"view tapped");
UIView *view = sender.view;
NSLog(#"view tag is %lu", view.tag); //Always prints parent view tag.
if(view.tag == 10){
NSLog(#"tag1 tapped"); // not called
}
if(view.tag == 20){
NSLog(#"tag 2 tapped"); // not called
}
}
You can detect subview using following code, I just tested creating sample project.
-(void) actionForViewTapped:(UITapGestureRecognizer*)sender {
NSLog(#"view tapped");
UIView *view = sender.view;
CGPoint loc = [sender locationInView:view];
UIView* subview = [view hitTest:loc withEvent:nil];
NSLog(#"view tag is %lu", subview.tag); //will print Subview tag.
if(view.tag == 10){
NSLog(#"tag1 tapped");
}
if(view.tag == 20){
NSLog(#"tag 2 tapped");
}
}
A UIGestureRecognizer is to be used with a single view.
If you want to use UIGestureRecognizer you will have to create one for each view, calling the same method.

iOS: Handling long press and drag to select another button. (Like the keyboard)

I'm having a hard time finding the right documentation for how to handle touch events in order to support similar behavior to the keyboard.
What I want is a button that when I long press it, it shows a custom view controller above the button, but I want the user to be able to drag their finger to one of the other buttons (without taking their finger off the screen).
I have the button with a long press and it's custom view controller all setup and working. What I can't figure is how to support dragging from the first button over to the other button in the view controller to be able to select it.
I've tried using a subclassed UIButton where I tried this:
[self addTarget:self action:#selector(onDragOver:) forControlEvents:UIControlEventTouchDragEnter];
But that doesn't work.
I also found this question How to track button selection after long press? which is precisely the functionality I'm trying to duplicate. But there are no answers.
Here's my solution. The trick is you have to use hitTest:.
First you add a gesture recognizer to the button that is a normal button - the button that you want to open a context menu / custom view controller.
Then in your gesture recognizer callback, you use hitTest: to figure out if the user is over a custom button of yours and update it's state manually.
- (id) init {
//add a long press gesture recognizer
UILongPressureGestureRecognizer * gesture = [[UILongPressureGestureRecognizer alloc] initWithTarget:self action:#selector(onLongTap:)];
[self.myButton addGestureRecognizer:gesture];
}
- (void) onLongTap:(UIGestureRecognizer *) gesture {
if(gesture.state == UIGestureRecognizerStateBegan) {
//display your view controller / context menu over the button
}
if(gesture.state == UIGestureRecognizerStateEnded) {
//gesture stopped, use hitTest to find if their finger was over a context button
CGPoint location = [gesture locationInView:self.view];
CGPoint superviewLocation = [self.view.superview convertPoint:location fromView:self.view];
UIView * view = [self.view.superview hitTest:superviewLocation withEvent:nil];
if([view isKindOfClass:[MMContextMenuButton class]]) {
//their finger was over my custom button, tell the button to send actions
MMContextMenuButton * button = (MMContextMenuButton *) view;
[self hideAndSendControlEvents:UIControlEventTouchUpInside];
if(self.draggedContextMenuButton == button) {
self.draggedContextMenuButton = nil;
}
}
if(self.draggedContextMenuButton) {
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
self.draggedContextMenuButton = nil;
}
if(gesture.state == UIGestureRecognizerStateChanged) {
//gesture changed, use hitTest to see if their finger
//is over a button. Manually have to tell the button
//that it should update it's state.
CGPoint location = [gesture locationInView:self.view];
CGPoint superviewLocation = [self.view.superview convertPoint:location fromView:self.view];
UIView * view = [self.view.superview hitTest:superviewLocation withEvent:nil];
if([view isKindOfClass[MMContextMenuButton class]]) {
MMContextMenuButton * button = (MMContextMenuButton *) view;
if(self.draggedContextMenuButton != button) {
[self.draggedContextMenuButton dragOut];
}
self.draggedContextMenuButton = button;
[button dragOver];
}
}
}
//////////////
#import "MMContextMenuButton.h"
#import "MMContextMenus.h"
#implementation MMContextMenuButton
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
self.layer.cornerRadius = 4;
self.adjustsImageWhenHighlighted = FALSE;
self.adjustsImageWhenDisabled = FALSE;
self.backgroundColor = [UIColor clearColor];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[self setTitleColor:[UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1] forState:UIControlStateNormal];
[self addTarget:self action:#selector(onHighlight:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:#selector(onRelease:) forControlEvents:UIControlEventTouchUpOutside&UIControlEventTouchUpOutside];
return self;
}
- (void) onHighlight:(id) sender {
self.backgroundColor = [UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1];
}
- (void) onRelease:(id) sender {
self.backgroundColor = [UIColor clearColor];
}
- (void) hideAndSendControlEvents:(UIControlEvents) events {
[self dragOut];
[self sendActionsForControlEvents:events];
[[MMContextMenus instance] hideContextMenus];
}
- (void) dragOver {
self.highlighted = TRUE;
self.backgroundColor = [UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1];
}
- (void) dragOut {
self.highlighted = FALSE;
self.backgroundColor = [UIColor clearColor];
}
#end

How to make table scrolling work: UIControl within UITableView within UIControl

Here's the setup: I have UIControls in table cells that allow sliding from right to left for a delete function (like Clear)
The table cells live inside a UITableView.
The TableView lives inside another UIControl that allows swiping from left to right or right to left in order to change days. When this happens a new TableView gets created to the right or left of the main one, and the new one is pulled in from left or right until a threshold is met and an animation takes over and then replaces the old with the new.
In some conditions all of these interactions actually work correctly. The issue is that after a couple of interactions (table slides seem to be problematic) it becomes difficult / impossible to scroll the table.
Here is the code for the TableViewSlider (the top level UIControl that contains the TableViews). Any ideas would be greatly appreciated!
#implementation OSETableViewSlider
- (void) initialize {
self.backgroundColor = [UIColor backgroundFlatColor];
self.mainTableView = [self createUITableView];
self.mainTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height);
self.mainTableView.hidden = NO;
[self addSubview:self.mainTableView];
self.transitionInProgress = NO;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if(self) {
[self initialize];
}
return self;
}
- (UITableView *)createUITableView {
UITableView *newTable = [[UITableView alloc] init];
newTable.hidden = YES;
newTable.separatorStyle = UITableViewCellSeparatorStyleNone;
newTable.scrollEnabled = YES;
newTable.bounces = YES;
newTable.dataSource = self;
newTable.delegate = self;
newTable.backgroundColor = [UIColor backgroundFlatColor];
return newTable;
}
- (void)setFrame:(CGRect)frame {
super.frame = frame;
self.mainTableView.frame = CGRectMake(0,0, frame.size.width, frame.size.height);
}
- (void)transitionToDate:(NSDate *)date fromRight:(BOOL)rightToLeft {
[self.viewController beginTransitionToDate:date];
self.transitionTableView = [self createUITableView];
self.transitionTableView.frame = CGRectMake( rightToLeft ? self.frame.size.width : (-1 * self.frame.size.width), 0,
self.frame.size.width, self.frame.size.height );
self.transitionTableView.hidden = NO;
[self addSubview:self.transitionTableView];
self.transitionInProgress = YES;
[UIView animateWithDuration:0.2f animations:^{
self.transitionTableView.frame = CGRectMake(0,0, self.frame.size.width, self.frame.size.height);
self.mainTableView.frame = CGRectMake( rightToLeft ? (-1 * self.frame.size.width) : self.frame.size.width, 0,
self.frame.size.width, self.frame.size.height);
} completion:^(BOOL completed){
[self.viewController endTransitionDidChange:YES];
[self.mainTableView removeFromSuperview];
self.mainTableView = self.transitionTableView;
self.transitionInProgress = NO;
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.viewController activityCountForTransition:(tableView!=self.mainTableView)];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self.viewController cellNumber:indexPath.item forTransition:(tableView!=self.mainTableView)].frame.size.height;
}
- (void)layoutSubviews {
if(!self.transitionInProgress) {
[self.mainTableView setFrame:CGRectMake(0,0, self.frame.size.width, self.frame.size.height)];
}
}
- (BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
NSLog(#"begin track");
self.locationInView = [touch locationInView:self.superview];
self.fingerTracking = YES;
self.fingerMoved = NO;
self.transitionTableView = nil;
return YES;
}
- (CGFloat) calcOffsetForTouch:(UITouch *)touch {
CGFloat fingerOffset = [touch locationInView:self.superview].x - self.locationInView.x;
return fingerOffset + self.startingOffset;
}
- (BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
self.fingerMoved = YES;
CGFloat offset = [self calcOffsetForTouch:touch];
//NSLog(#"offset is: %f flarb: %f", offset, fabs(offset));
if(offset < 0 && (!self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) {
[self.viewController beginTransitionToDate:[OSEUtils daysOffset:1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]]];
[self.transitionTableView removeFromSuperview];
self.transitionTableView = [self createUITableView];
self.transitioningLeft = YES;
NSLog(#"going left");
[self addSubview:self.transitionTableView];
[self.transitionTableView reloadData];
}
if(offset > 0 && (self.transitioningLeft || [OSEUtils isNull:self.transitionTableView])) {
[self.viewController beginTransitionToDate:[OSEUtils daysOffset:-1 fromDate:self.viewController.selectedDate withTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]]];
[self.transitionTableView removeFromSuperview];
self.transitionTableView = [self createUITableView];
self.transitioningLeft = NO;
NSLog(#"going right");
[self addSubview:self.transitionTableView];
[self.transitionTableView reloadData];
}
CGFloat mult = self.transitioningLeft ? 1 : -1;
if(fabs(offset) > (self.frame.size.width / 3.0f)) {
if(self.transitioningLeft) {
offset = -1 * self.frame.size.width;
} else {
offset = self.frame.size.width;
}
[UIView animateWithDuration:0.2f animations:^{
self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0,
self.frame.size.width, self.frame.size.height);
} completion:^(BOOL finished) {
[self.mainTableView removeFromSuperview];
if(self.transitioningLeft) {
[self.viewController.daySelector jumpToNext];
} else {
[self.viewController.daySelector jumpToPrevious];
}
self.mainTableView = self.transitionTableView;
self.transitionTableView = nil;
[self.viewController endTransitionDidChange:YES];
}];
return NO;
}
self.mainTableView.frame = CGRectMake(offset, 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(offset + (mult * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height);
self.transitionTableView.hidden = NO;
return YES;
}
- (void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
NSLog(#"end tableslide track");
[UIView animateWithDuration:0.2f animations:^{
self.mainTableView.frame = CGRectMake(0,0,self.frame.size.width, self.frame.size.height);
self.transitionTableView.frame = CGRectMake(((self.transitioningLeft ? 1 : -1 ) * self.frame.size.width), 0, self.frame.size.width, self.frame.size.height);
} completion:^(BOOL completion){
[self.transitionTableView removeFromSuperview];
self.transitionTableView = nil;
[self.viewController endTransitionDidChange:NO];
}];
self.fingerTracking = NO;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *tableHitTest = [self.mainTableView hitTest:point withEvent:event];
if([tableHitTest isKindOfClass:[OSECellPanelControl class]]) {
return tableHitTest;
} else {
return self;
}
}
#end
Why are you creating a new UITableView when the user swipes left or right? It would be much more efficient to use the built-in deleteRowsAtIndexPath: and insertRowsAtIndexPath: methods to animate the rows sliding in and out without having to slide in and out entire UITableView's.
You can take a look at this for a reference on animating the tableview content changes as you swipe across dates.
I don't know about your current set up, but when I tried this exact same thing with swipeable UITableViewCell's and it's superview being swipe able, I had issues with getting the interaction that I wanted. If this is contributing to your problem, you can look at detecting where the user swipes. If the user swipes within a specific offset from the left and right edge of the UITableViewCell, then it swipes the cell, anything outside of that offset (center of the cell) would have the UITableView itself swiped. You would then animate out the deleting and insertion of the new rows.
Also, by re-instancing a new UITableView each time, you are forcing your UITableViewCell's to be re-instanced each time as well. By using the delete and insert methods, you can continue to use your existing cells via the dequeueReusableCellWithIdentifier method. Each time you re-instance the UITableView, your cells are set to nil and discarded requiring the new tableview to create complete new instances of your cells. This is extremely inefficient.
You're getting in deep with touch tracking and hit detection. Use a higher level API instead - gesture recognisers. With gestures you can set precedence (this one has to fail before this one can begin).
So, you want a couple of custom gestures on the container view (which no longer needs to be a control). These fail if the initial touch point isn't at the edge of the view (within some bound). These trigger the overall table view change.
And the table cells have swipe gestures that each require the custom ones to fail. These trigger your cell deletion logic.
Your idea share a few similarities with how the iOS7 unlock screen and calendar is built. In the unlock screen, you can swipe on notifications, move the notification list up and down, and swipe to unlock. In the calendar app, you can swipe to change the current day, or swipe the header to change the week. Thus I recommend watching the WWDC 2013 Session video #217 "Exploring Scroll Views on iOS 7" that explain and demonstrate how they have done it, and how to replicate the functionality.
Basically, what you could do (and what they did for the unlock screen and calendar screen) is: Either (A) nest UIScrollViews in a UITableView OR (B) use a swipe/pan gesture delegate on every cells, and (C) nest that UITableView along with every other UITableViews representing days in a UIScrollView with paging control enabled.
(A) will allow you to expose a delete button in cells. You could either put the delete button under the UIScrollView that sits in the cell in a way that sliding the content uncover it.
(B) will allow you to track a gesture in cells, cancel it if required, and play with the cell's contentView to display a delete button.
(C) will allow you to swipe from one UITableView to another quite easily, and with paging enable you will get a free "snap into place or bounce back" animation PLUS you can easily reuse two UITableViews instead of allocating one per day.
Personally, I would go with (B) and (C).
Turns out there was a problem with my hitTest method. Replacing [self.mainTableView hitTest...] with [super hitTest...] solved my problem. I think I was messing up some coordinates that was causing this method to return nil when it should have returned a view. I'm not 100% sure exactly what is wrong with it, but it does work better now.

IOS: UIgesture for drag an drop

In my app I should implement the drag and drop of a imageView; the problem is that my imageView is inside a scrollview; it's my code
- (void) viewDidLoad{
[super viewDidLoad];
UILongPressGestureRecognizer *downwardGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(dragGestureChanged:)];
[scrollViewAlfabeto addGestureRecognizer:downwardGesture];
for (UIGestureRecognizer *gestureRecognizer in myscrollView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:downwardGesture];
}
}
- (void) dragGestureChanged:(UIPanGestureRecognizer*)gesture
{
CGPoint point = [gesture locationInView:scrollViewAlfabeto];
if (gesture.state == UIGestureRecognizerStateBegan)
{
[imageViewToMove removeFromSuperview];
[self.view addSubview:imageViewToMove];
UIView *draggedView = [myscrollView hitTest:point withEvent:nil];
if ([draggedView isKindOfClass:[UIImageView class]])
{
imageViewToMove = (UIImageView*)draggedView;
}
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
imageToMove.center = point;
}
else if (gesture.state == UIGestureRecognizerStateEnded ||
gesture.state == UIGestureRecognizerStateCancelled ||
gesture.state == UIGestureRecognizerStateFailed)
{
// Determine if dragged view is in an OK drop zone
// If so, then do the drop action, if not, return it to original location
NSLog(#"point.x final:%f", point.x);
NSLog(#"point.y final:%f", point.y);
if (CGRectContainsPoint(goal.frame, point)){
imageToMove.frame = CGRectMake(167, 159, 100, 100);
}
else{
[imageToMove removeFromSuperview];
[myscrollView addSubview:imageToMove];
[imageToMove setFrame:CGRectMake(12, 38, 100, 100)];
imageToMove = nil;
}
}
}
Then with my code I'm able to take an imageView from scrollView with longpress, drag it inside "self.view"; also if I drop this imageView over another imageView in self.view it puts on it. It work fine. But I have two problems:
1- when I drag this imageView and I do
[imageViewToMove removeFromSuperview];
[self.view addSubview:imageViewToMove];
the image view don't appear under my finger but in other position and I want that it remains under my finger
2- This code work only the first time when I launch my viewcontroller, because If I don't drop the imageview over other imageview inside self.view, itr return inside scrollview, but If I want drag it a second time, it don't work.
Can you help me?
I'm not advanced in objc, but...
Allow user ineraction [self.view userInteractionEnabled:YES];
Try [self.view setMultipleTouchEnabled:YES];
Taken from the documentation of UIView in relation to userInteractionEnabled:
Discussion
When set to NO, user events—such as touch and
keyboard—intended for the view are ignored and removed from the event
queue. When set to YES, events are delivered to the view normally. The
default value of this property is YES.
During an animation, user interactions are temporarily disabled for
all views involved in the animation, regardless of the value in this
property. You can disable this behavior by specifying the
UIViewAnimationOptionAllowUserInteraction option when configuring the
animation.
Hope it works

Why is UIGestureRecognizer being called on my textField clear button?

I have a UITableView with a gesture recognizer added:
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
[myTableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO;
... everything works fine when tapping on the tableview to dismiss the keyboard. My problem is, my hideKeyboard method also calls when tapping on the "clear" button on my UITextField. Very strange.
commentTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 310, 35)];
commentTextField.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;
commentTextField.borderStyle = UITextBorderStyleRoundedRect;
commentTextField.textColor = [UIColor blackColor]; //text color
commentTextField.font = [UIFont fontWithName:#"Helvetica" size:14.0]; //font size
commentTextField.placeholder = #"Enter a comment..."; //place holder
commentTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
commentTextField.keyboardType = UIKeyboardTypeDefault; // type of the keyboard
commentTextField.returnKeyType = UIReturnKeySend; // type of the return key
commentTextField.clearButtonMode = UITextFieldViewModeAlways; // has a clear 'x' button to the right
commentTextField.delegate = self;
[commentTextField setHidden:NO];
[commentTextField setEnabled:YES];
[commentTextField setDelegate: self];
hide keyboard method:
- (void) hideKeyboard{
if(keyboard){
[commentTextField resignFirstResponder];
[UIView animateWithDuration:.3
delay:.0
options:UIViewAnimationCurveEaseInOut
animations:^{ // start animation block
[myTableView setFrame:CGRectMake(0, myTableView.frame.origin.y + 216, myTableView.frame.size.width, myTableView.frame.size.height)];
}
completion:^(BOOL finished){
}];
keyboard = 0;
}
}
Any help would be appreciated, thanks!
The following is a little more general - it's not coupled to your specific views:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UITextField class]] ||
[touch.view isKindOfClass:[UIButton class]])
{
return NO;
}
return YES;
}
Also, don't forget to set the delegate for the gesture recognizer, and mark the class as implementing the UIGestureRecognizerDelegate protocol.
I had the same issue. I also implemented the following method in my view:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ((touch.view == self.textField) && (gestureRecognizer == self.tapGestureRecognizer))
{
return NO;
}
return YES;
}
But it still didn't work. So I set a break in the method and saw that when I click the field, touch.view would be set to it but when I clicked on the clear button it was coming in as a UIButton*. At that point it was obvious what was happening and what to do to fix it. The below resolves the issue.
if((touch.view == self.textField || [self.textField.subviews containsObject:touch.view]) && (gestureRecognizer == self.tapGestureRecognizer))
{
return NO;
}
My issue with Ezmodius' approach is that he depends on a property called 'textField' and my UIViewController is a controller from which all my other UIViewControllers inherit, so i needed to implement a more generic approach: whenever there was a textfield in any UIViewController that needed to be cleared, i implemented the following (inside the same gestureRecognizer method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UITextField class]] ||
([touch.view isKindOfClass:[UIButton class]] && [touch.view.superview isKindOfClass:[UITextField class]]))
{
return NO;
}
return YES;
}
So basically im checking whether it is a textfield or a button whose superview is a textfield (in this case, the clear button inside the textfield) and it works like a charm for me. I implemented this in my base UIViewController class and it works for every page where this happens.

Resources