Showing posts with label long press. Show all posts
Showing posts with label long press. Show all posts

Thursday, January 4, 2018

Tappable links in UITextView

UITextView’s Data Detectors are helpful in detecting the urls/phone numbers in the content we display in it. 



However, links in UITextView don’t work on press, only when long pressing them works.

The work around for this is to add a Tap Gesture as shown below.


Swift




  let tapRecognizer = UITapGestureRecognizer(target: self, 
                         action: #selector(self.tappedTextView))

  sampleNotes.addGestureRecognizer(tapRecognizer)

    @objc func tappedTextView(tapGesture: 
                                    UIGestureRecognizer) {

        let textView = tapGesture.view as! UITextView
        let tapLocation = tapGesture.location(in: textView)
        let textPosition = textView.closestPosition(to: 
                                                                   tapLocation)
        let attr: NSDictionary = textView.textStyling(at: 
                      textPosition!, in: .forward)! as NSDictionary

        if let url: NSURL = attr[NSAttributedStringKey.link] as? 
                                                                        NSURL 
         {
            tappedOn(url: url as URL)
        }
    }
    
    func tappedOn(url: URL) {
        print(url)
    }



Objective C




   
  UITapGestureRecognizer *tapGesture = 
           [[UITapGestureRecognizer alloc] initWithTarget:cell 
                     action:@selector(tappedTextView:)];

    [sampleNotes addGestureRecognizer:tapGesture];

- (void)tappedTextView:
                    (UITapGestureRecognizer*)tapGesture {

    if (tapGesture.state != UIGestureRecognizerStateEnded) {
        return;
    }

    UITextView *textView = (UITextView *)tapGesture.view;

    CGPoint tapLocation = [tapGesture 
                                         locationInView:textView];

    UITextPosition *textPosition = [textView 
                              closestPositionToPoint:tapLocation];

    NSDictionary *attributes = [textView 
                                  textStylingAtPosition:textPosition 
                  inDirection:UITextStorageDirectionForward];

    NSURL *url = attributes[NSLinkAttributeName];

    if (url) {
        [self tappedOnLink:url];
    }
}



Here, We are getting the tap location and checking whether the tapped area is of a link.


Hope this post is useful. Feel Free to comment incase of any queries.


Sunday, January 24, 2016

Objective C long press event

Sometimes, we need long press event, especially in games rather than just a tap or touch event.

For example, I need to change the template in an application on tapping the template icon and this change should be only a local change. If I need to change the template and also need to save the template ID in the server, Obviously I need another event on the template icon. 

One way is to write double tap event on that control, Which is not very handy. Another best approach is a long press event which users also feel very handy. Single tap local change and long press gives local as well as server change. In the usability point of view also this is a very good approach.


                         



Let's see how to write a long press event on a control (UIButton, UILabel..) in Objective-C.

Like UITapGestureRecognizer, we have UILongPressGestureRecognizer in Objective C. Let's see how to apply this to a control.

I have a label and I need to apply long press on it.


   
UILabel *lbl = [UILabel alloc] init];
   [lbl seTextColor:[UIColor whiteColor]];


As it is a static control, by default it's user interaction is disabled. We need to explicitly enable it. Otherwise, these labels won't respond to these recognizers.


  
[lbl setUserInteractionEnabled:YES];

  UILongPressGestureRecognizer *longPress =       
                           [[UILongPressGestureRecognizer allocinitWithTarget:self 
                                                                 action:@selector(longPressEvent:)];

  [longPress setMinimumPressDuration:3];

  longPress.delegate = (id <UIGestureRecognizerDelegate>)self;

  [lbl addGestureRecognizer:longPress];


I have added a long press gesture recognizer to the label. We can also set the minimum duration that user has to tap and hold on the control for this event. Unlike, tap events, these long press recognizers have states. Below are the UIGestureRecognizerState types.

    UIGestureRecognizerStatePossible,     
    UIGestureRecognizerStateBegan,    
    UIGestureRecognizerStateChanged,   
    UIGestureRecognizerStateEnded,     
    UIGestureRecognizerStateCancelled,      
    UIGestureRecognizerStateFailed,   
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

Here, we are concerned about only 2 states. 


 
- (void) longPressEvent:(UILongPressGestureRecognizer*)gesture{
    
    if (gesture.state == UIGestureRecognizerStateBegan ) {        
        
        [self.titleLabel setTextColor:[UIColor redColor]];
    }
    
    else if ( gesture.state == UIGestureRecognizerStateEnded) {

        self.titleLabel.textColor = [UIColor whiteColor]
    }
    
 }



First one is UIGestureRecognizerStateBegan. This where you can confirm like long press is happening on the control. Here I am just changing the color of the label text control to highlight it.

Second one is, UIGestureRecognizerStateEnded. This is where you can confirm like user has stopped the long press on the control. Here I am rolling back the label's actual text color.




                         


Hope this post is useful. Feel free to comment incase of any queries.