littleJoe

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
13章 UIGestureRecognizer and UIMenuController
    创建自定义手势
    按钮: 例如长按文本出现的按钮,自定义

    UILongPressGestureRecognizer
    UIPanGestureRecognizer and Simultaneous Recognizers


    UIMenuController and UIResponderStajdardEditAction

-----------------------------------------------------------------------------------------------------------------------------------------

Chapter 13 UIGestureRecognizer and UIMenuController.

1. gesture like pinch or swipe
2.you don't instantiate UIGestureRecognizer, system has some subclass that u can use for the particular gesture. the action message like:
- (void) action:(UIGestureRecognizer *)gestureRecognizer;
** when recognizing a gesture,the gesture recognizer intercepts the touch destined for the view.so the like touchBegan: may not receive. the flow:
    UIApplication --touch event--> UIWindow --touch event--> UIGestureRecognizer -- recognized gesture(yes/no)--> if yes: send action: to view; if not,send touchesBegan:withEvent: to the view.
*********************
UITapGestureRecognizer: double tap screen and clear the lines:
-(instancetype)initWithFrame:(CGRect)r
{
//......
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapRecognizer];
 
return self;
}
 
-(void)doubleTap:(UIGestureRecognizer *)gr
{
// for a double tap, u don't need information from gr
[self.linesInProgress removeAllObjects];
[self.finishedLines removeAllObjects];
[self setNeedsDisplay];
}
the flow: 1.send touchesBegan:; 2.recognized the double tap, send doubleTap: 3.send touchedCancelled:.
*** so if u don't want the 1 happens,set like:
doubleTapRecognizer.delaysTouchesBegan = YES;
 
----------------multiple gesture recognizers----------
like: if u add a tap and double tap to a view,when u double the view,it will send to tap first and then send to doubleTap. So, the truth is : if u double tap the screen,the tap may not what u want to trigger,so set like:
[tapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
means during the double tap happen, the one tap will force to fail.
 
***** one tap to choose a line*******
when select a line,a menu appear right at the tap point.
 
UIMenuController, 
UIMenuItem (the list that controller has) each item has a title and action. the action message is send to the first responder of the window,so there is not the gesture,view 's business///
***There is only one UIMenuController per Application, u can fill it with menu items to it, and give it a rectangle to present form,and set it to be visible.******
 
do like:
-(void) tap:(UIGestureRecognizer *)gr
{
// get the tap location
CGPoint point = [gr locationInView:self];
self.selectedLine = [self lineAtPoint:point];
if(self.selectedLine){
//!!! make ourselves the target of menu item
// action messages
[self becomeFirstResponder];
// grab the msnu controller
UIMenuController *menu = [UIMenuController sharedMenuController];
// create delete item
UIMenuItem *deleteItem = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(deleteLine:)];
menu.menuItems = @[deleteItem];
// show it
[menu setTargetRect:CGRectMake(point.x,point.y,2,2) inView:self];
[menu setMenuVisible:YES animated:YES];
}else{
// hide menu controller
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
}
[self setNeedsDisplay];
}
 
 
 
*****if u have a custom class needs to become the first responder,u must override canBecomeFirstResponder:
-(BOOL)canBecomeFirstResponder
{
return YES;
}
 
 
*** what u do below, when u tap a line, the menu is not shown at all. the reason:
1.becomeFirstResponder       [done]
2.implemented each item's selector  [not yet]
 
so:
-(void) deleteLine:(BNRLine *) line
{
[self.finishedLines removeObject:self.selectedLine];
[self setNeedsDisplay];
}
 ======================================
UILongPressGestureRecognizer
***when u hold down on a line (a long press),u selected the line and then drag it around by dragging you finger (pan)
as add other gesture add the long press gesture.
notice that need more than 0.5s,u can change it by set minimumPressDuration.
 
%%the below gesture is the simple gesture: by the time it is recognized,the gesture is over, and the message has been delivered . 
%% long press is occurs over time and is defined by three separate events.
UIGestureRecognizerStatePossible,   [press a while]
UIGestureRecgonizerStateBegan,    [like at lease 0.5]
UIGestureRecognizerStateEnded. [remove finger]
 
the state property
 
*************
-(void)longPress:(UIGestureRecognizer *)rg
{
if(rg.state == UIGestureRecognizerStateBegan){
CGPoint *point = [rg locationInView:self];
self.selectedLine = [self lineAtPoint:point];
if(self.selectedLine){
self.linesInProgress removeAllObjects];
}
}else if(rg.state == UIGestureRecognizerStateEnded){
self.selectedLine = nil;
}
[self setNeedsDisplay];
}
 
------------UIPanGestureRecognizer Simultaneous Recognizer---------------
pan: move the line with finger around the screen
 
** normally ,a gesture recognizer does not share the touches.just like eat the touch,and no other recognizer get a chance to handle it. But this is bad ,u need the long press and panning.
 
do like:
@interface BNRDrawView () <UIGestureRecognizerDelegate>
 
@property (nonatomic,strong) UIPanGestureRecognizer *moveRecognizer;
// other code ....
 
@end
 
// code in implementation
 
self.moveRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveLine:) ];
self.moveRecognizer.delegate = self;
self.moveRecognizer.cancelsTouchesInView = NO;
[self addGestureRecognizer:self.moveRecognizer];
 
*****u just need to implementation one method about UIGestureRecognizerDelegate protocol,:
gestureRecognizer:shouldRecognizerSimultaneouslyWithGestureRecognizer:
 
&&when a recognizer hold the gesture,at the same time ,another recognizer recognized the gesture,so, it will send the message.
 
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizerShouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)other
{
if(gestureRecognizer == self.moveRecognizer){
return YES;
}
return NO;
}
 
-(void)moveLine:(UIPanGestureRecognizer *)gr
{
if(!self.selectedLine){
return;
}
if(gr.state == UIGestureRecognizerStateChanged){
CGPoint translation = [gr translationInView:self]
CGPoint begin = self.selectedLine.begin;
CGPoint end = self.selectedLine.end;
begin.x += translation.x;
begin.y += translation.y;
end.x += translation.x;
end.y += translation.y;
self.selectedLine.begin = begin;
self.selectedLine.end = end;
[self setNeedsDisplay];
 
//************]
[gr setTranslation:CGPointZero inView:self];
}
}

 

posted on 2015-02-04 23:09  littleJoe  阅读(155)  评论(0)    收藏  举报