第一章:多点触摸与手势检测

2023-10-30

一、响应者链

只要继承了UIResponder的对象就可作为事件的响应者,实际上UIControl继承了UIView,UIView又继承了UIResponder,由此可见,所有的对象都可作为事件的响应者。

当用户与某个控件交互时,该控件将作为“第一响应者(First Responder)”,第一响应者将作为响应者链的开始,该事件首先被发送给第一响应者(也就是用户触摸屏幕的控件)。事件将沿着响应者链一直向下传播,直到被某个响应者处理。事件响应者链的典型传播路线如下:

First Responder —> First Responder的视图控制器(如果有)—>父容器(如果有)—>父容器的视图控制器(如果有)—>UIWindow—>UIApplication—>应用程序委托对象

如果某个响应者“截获”了某个事件,那么该响应者要根据条件决定是否处理该事件。当响应者无法处理该事件时,则需要在处理方法中手动传递该事件。例如如下代码:

- (void)handleTapEvent:(UITapGestureRecognizer *)event{
    if (YES) {
        //处理事件
    }else{
        OtherTapView* view = (OtherTapView *)self.nextResponder;
        [view handleTapEvent:event];
    }
}

二、响应触碰方法

如果希望自定义控件可以响应用户的触碰事件,则可以通过通过UIResponder的如下四个方法实现:

  • ①、- (void)touchesBegan:(NSSet )touches withEvent:(UIEvent )event;//当用户手指开始接触控件或窗口事件时激发该方法;
  • ②、- (void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event;//当用户手指在控件上移动时激发该方法;
  • ③、- (void)touchesEnded:(NSSet )touches withEvent:(UIEvent )event;//当用户手指结束触碰控件激发该方法;
  • ④、- (void)touchesCancelled:(NSSet )touches withEvent:(UIEvent )event;//当系统事件(比如内存底事件)终止了触碰事件时激发该方法。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     NSLog(@"%ld",[touches count]);
     NSLog(@"%ld",[[touches anyObject]tapCount]);
     CGPoint point = [[touches anyObject] locationInView:self.view];
}

注意:

  • ①、第一个NSSet类型的参数代表了用户同时触碰控件的多个手指,如果该用户用3个手指触碰该控件,那么该touches参数中将会包含3个UITouch对象;
  • ②、UITouch对象代表一个触碰事件,该对象提供了一个tapCount属性,该属性用于返回用户触碰屏幕的次数,比如用户只是轻轻的触碰屏幕一次,那么该属性将返回1.如果该属性返回3,则代表用户快速触碰了3次屏幕.
  • ③、UITouch还提供了locationInView:方法来获取该触碰事件在UIView控件中的碰触位置.

三、使用手势处理器(UIGestureRecognizer)

UIGestureRecognizer提供了如下子类:

  • ①、UITapGestureRecognizer:处理用户点击手势的手势处理器;
  • ②、UIPinchGestureRecognizer:处理用户捏合手势的手势处理器;
  • ③、UIRotationGestureRecognizer:处理用户旋转手势的手势处理器;
  • ④、UISwipeGestureRecognizer:处理用户滑动手势的手势处理器;
  • ⑤、UIPanGestureRecognizer:处理用户拖动手势的手势处理器;
  • ⑥、UILongPressGestureRecognizer:处理用户长按手势的手势处理器;

使用手势处理器处理用户触碰手势的编程步骤如下:

  1. 、根据程序要处理的手势创建对象的手势处理器对象。创建手势处理器时需要制定target和action参数—当该控件上发生触碰手势后,该target对象的action方法将会被激发。
  2. 、如果该UI控件不允许交互,则将该UI控件的userInteractionEnable属性设为YES;如果希望该控件可支持多点触碰,还需要将multipleTouchEnable设为YES.
  3. 、调用UI控件的addGestureRecognizer:方法添加该手势处理器;

UIGestureRecognizer作为所有手势处理器的基类,它提供了如下常用的方法和属性:

  • (1)、- (CGPoint)locationInView:(UIView*)view;返回该手势在view控件中的触碰位置;
  • (2)、- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view;返回该手势中第touchIndex个触碰点在view控件中的位置;
  • (3)、- (NSUInteger)numberOfTouches;返回该手势包含触碰点的数量(也就是用户用了几个手指进行触碰);
  • (4)、@property(nonatomic,readonly) UIView *view;返回激发该手势的UI控件;
  • (5)、@property(nonatomic, getter=isEnabled) BOOL enabled;用户设置和返回该手势处理器是否可用;
  • (6)、@property(nonatomic,readonly) UIGestureRecognizerState state;获取该手势所处的状态,该状态分为如下几种:
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    UIGestureRecognizerStatePossible,
    UIGestureRecognizerStateBegan,
    UIGestureRecognizerStateChanged,
    UIGestureRecognizerStateEnded,
    UIGestureRecognizerStateCancelled,
    UIGestureRecognizerStateFailed,
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
};

1、使用UITapGestureRecognizer处理点击事件

UITapGestureRecognizer还提供了如下两个属性:

  • (1)、@property (nonatomic) NSUInteger numberOfTapsRequired;指定该手势处理器只处理几次触碰事件;
  • (2)、@property (nonatomic) NSUInteger numberOfTouchesRequired;指定该手势处理器只处理几个手指的触碰事件.

实例:

- (void)viewDidLoad {
    [super viewDidLoad];
    gv = [[UIView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    label = [[UILabel alloc]initWithFrame:CGRectMake(20, 50, gv.frame.size.width - 40, 40)];
    [gv addSubview:label];
    self.view.backgroundColor = [UIColor lightGrayColor];
    for (int i = 0; i < 6; i ++) {
        //创建手势处理器,指定使用该控制器的handleTap:方法处理手势
        UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
        //设置该点击手势处理器只处理i次连击事件
        gesture.numberOfTapsRequired = i;
        //设置该点击手势处理器只处理两个手指的触碰事件
        gesture.numberOfTouchesRequired = 2;
        //为gv控件添加手势处理器
        [gv addGestureRecognizer:gesture];
    }
}
- (void)handleTap:(UITapGestureRecognizer *)gesture{
    NSInteger touchNum = gesture.numberOfTouches;
    NSUInteger tapNum = gesture.numberOfTapsRequired;
    label.text = [NSString stringWithFormat:@"用户使用%ld个手指进行触碰,触碰次数为:%ld",touchNum,tapNum];
    //指定2秒后清除label的文本
    [label performSelector:@selector(setText:) withObject:@"" afterDelay:5];
}

2、使用UIPinchGestureRecognizer处理捏合事件

UIPinchGestureRecognizer定义了如下两个属性来获取捏合相关信息:

  • (1)、@property (nonatomic) CGFloat scale;获取捏合的比例;
  • (2)、@property (nonatomic,readonly) CGFloat velocity;获取捏合的速度;

实例:

- (void)viewDidLoad {
    [super viewDidLoad];
    gv = [[UIView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    label = [[UILabel alloc]initWithFrame:CGRectMake(20, 50, gv.frame.size.width - 40, 80)];
    label.numberOfLines = 2;
    [gv addSubview:label];
    self.view.backgroundColor = [UIColor lightGrayColor];
    UIPinchGestureRecognizer* gesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
    //为gv控件添加手势处理器
    [gv addGestureRecognizer:gesture];
}
- (void)handlePinch:(UIPinchGestureRecognizer *)gesture{
    //获取用户捏合的速度和比例
    CGFloat velocity = gesture.velocity;
    CGFloat scale = gesture.scale;
    label.text = [NSString stringWithFormat:@"用户捏合的速度为:%g,比例为:%g",velocity,scale];
    //指定2秒后清除label的文本
    [label performSelector:@selector(setText:) withObject:@"" afterDelay:5];
}

实例:通过捏合手势缩放图片

- (void)viewDidLoad {
    [super viewDidLoad];
    [UIApplication sharedApplication].statusBarHidden = YES;
    srcImage = [UIImage imageNamed:@"妞.png"];
    //设置图片直接显示在中间(不进行任何缩放)
    self.view.contentMode = UIViewContentModeCenter;
    self.view.backgroundColor = [UIColor lightGrayColor];
    gv = [[UIImageView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    currentSize = CGSizeMake(self.view.frame.size.width - 20, 200);
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    gv.image = srcImage;
    //创建UIPinchGestureRecognizer手势处理器,该手势处理器激发scaleImage:方法
    UIPinchGestureRecognizer* gesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(scaleImage:)];
    [gv addGestureRecognizer:gesture];
}
//imageView进行缩放
- (void)scaleImage:(UIPinchGestureRecognizer *)gesture{
    gv.bounds = CGRectMake(0, 0, currentSize.width * gesture.scale, currentSize.height * gesture.scale);
    if (gesture.state == UIGestureRecognizerStateEnded) {
        currentSize = CGSizeMake(currentSize.width * gesture.scale, currentSize.height * gesture.scale);
    }
}

3、使用UIRotationGestureRecognizer处理旋转手势

UIRotationGestureRecognizer定义了如下两个属性来获取旋转相关信息:

  • (1)、@property (nonatomic)CGFloat rotation;获取旋转角度;
  • (2)、@property (nonatomic,readonly) CGFloat velocity;获取旋转速度;

实例:通过旋转手势旋转图片

- (void)viewDidLoad {
    [super viewDidLoad];
    srcImage = [UIImage imageNamed:@"妞.png"];
    //设置图片直接显示在中间(不进行任何缩放)
    self.view.backgroundColor = [UIColor lightGrayColor];
    gv = [[UIImageView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    currentSize = CGSizeMake(self.view.frame.size.width - 20, 200);
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    gv.image = srcImage;
    //创建UIPinchGestureRecognizer手势处理器,该手势处理器激发scaleImage:方法
    UIRotationGestureRecognizer* gesture = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotateImage:)];
    [gv addGestureRecognizer:gesture];
}
- (void)rotateImage:(UIRotationGestureRecognizer *)gesture{
    //根据当前缩放的比例计算缩放后的目标图片大小
    gv.transform = CGAffineTransformMakeRotation(imageRotate + gesture.rotation);
    if (gesture.state == UIGestureRecognizerStateEnded) {
        imageRotate += gesture.rotation;
    }
}

4、使用UISwipeGestureRecognizer处理轻扫手势

UISwipeGestureRecognizer定义了如下两个属性来设置相关信息:

  • (1)、@property(nonatomic) NSUInteger numberOfTouchesRequired;指定该手势处理器只处理几个手指的触碰事件;
  • (2)、@property(nonatomic) UISwipeGestureRecognizerDirection direction;指定该手势处理器处理该方向的轻扫.该属性支持:
typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
    UISwipeGestureRecognizerDirectionRight = 1 << 0,
    UISwipeGestureRecognizerDirectionLeft  = 1 << 1,
    UISwipeGestureRecognizerDirectionUp    = 1 << 2,
    UISwipeGestureRecognizerDirectionDown  = 1 << 3
};

实例:

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置图片直接显示在中间(不进行任何缩放)
    self.view.backgroundColor = [UIColor lightGrayColor];
    gv = [[UIImageView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    label = [[UILabel alloc]initWithFrame:CGRectMake(20, 50, gv.frame.size.width - 40, 80)];
    label.numberOfLines = 2;
    [gv addSubview:label];
    for (int i = 0 ; i < 4; i ++) {
        //创建手势处理器,指定使用该控制器的handleSwipe:方法处理轻扫手势
        UISwipeGestureRecognizer* gesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipe:)];
        //设置该手势处理器只处理i个手指的轻扫手势
        gesture.numberOfTouchesRequired = 1;
        //指定该手势处理器只处理1 << i方向的轻扫手势
        gesture.direction = 1 << i;
        [gv addGestureRecognizer:gesture];
    }
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)gesture{
    //获取手势的方向
    NSUInteger direction = gesture.direction;
    //根据手势方向的值得到方向字符串
    NSString* dirStr = direction == UISwipeGestureRecognizerDirectionRight?@"向右":(direction == UISwipeGestureRecognizerDirectionLeft?@"向左":(direction == UISwipeGestureRecognizerDirectionUp?@"向上":@"向下"));
    NSLog(@"dirStr = %@",dirStr);
    NSUInteger touchNum = gesture.numberOfTouchesRequired;
    label.text = [NSString stringWithFormat:@"用户使用%ld个手指进行轻扫,方向为%@",touchNum,dirStr];
    //指定5秒后清除label的文本
    [label performSelector:@selector(setText:) withObject:@"" afterDelay:5];
}

5、使用UIPanGestureRecognizer处理拖动手势

UIPanGestureRecognizer定义了如下的方法来获取拖动相关信息:

  • (1)、@property (nonatomic) NSUInteger minimumNumberOfTouches;设置移动手势处理器最少需要几个手指拖动;
  • (2)、@property (nonatomic) NSUInteger maximumNumberOfTouches;设置移动手势处理器最多支持几个手指拖动;
  • (3)、- (CGPoint)translationInView:(UIView *)view;获取该拖动手势在指定控件上的位移.该方法返回一个CGPoint结构体数据,该结构体中x变量的值代表水平方向的位移,y变量的值代表了垂直方向的位移;
  • (4)、- (CGPoint)velocityInView:(UIView *)view; 获取该拖动手势在指定控件上的拖动速度.该方法返回一个CGPoint结构体数据,该结构体中x变量的值代表了水平方向的速度,y变量的值代表了垂直方向的速度.

例如:

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置图片直接显示在中间(不进行任何缩放)
    self.view.backgroundColor = [UIColor lightGrayColor];
    gv = [[UIImageView alloc]initWithFrame:CGRectMake(10, 200, self.view.frame.size.width - 20, 200)];
    gv.layer.borderWidth = 2;
    gv.layer.cornerRadius = 6;
    //设置gv控件支持用户交互
    gv.userInteractionEnabled = YES;
    //设置gv控件支持多点触碰
    gv.multipleTouchEnabled = YES;
    [self.view addSubview:gv];
    label = [[UILabel alloc]initWithFrame:CGRectMake(20, 50, gv.frame.size.width - 40, 80)];
    label.numberOfLines = 3;
    [gv addSubview:label];
    //创建手势处理器,指定使用该控制器的handlePan:方法处理手势
    UIPanGestureRecognizer* gesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
    //设置该手势处理器最少需要1个手指
    gesture.minimumNumberOfTouches = 1;
    //设置该手势处理器最多需要2个手指
    gesture.maximumNumberOfTouches = 2;
    [gv addGestureRecognizer:gesture];
}
//实现手势处理器的方法,该方法应该生命一个形参
//当该方法被激发时,手势处理器会作为参数传给该方法的参数
- (void)handlePan:(UIPanGestureRecognizer *)gesture{
    CGPoint velocity = [gesture velocityInView:gv];
    CGPoint translation = [gesture translationInView:gv];
    label.text = [NSString stringWithFormat:@"水平速度为:%g,垂直速度为:%g,水平距离为:%g,垂直距离为:%g",velocity.x,velocity.y,translation.x,translation.y];
}

6、使用UILongGestureRecognizer处理长按手势

UILongGestureRecognizer定义了如下属性来设置该手势处理器的相关信息:

  • (1)、@property (nonatomic) CFTimeInterval minimumPressDuration;指定用户至少在屏幕上按下多少秒才会触发该长安手指,该属性默认值为0.5;
  • (2)、@property (nonatomic) NSUInteger numberOfTapsRequired;指定必须使用几个手指在屏幕上长按才会触发该手势;
  • (3)、@property (nonatomic) CGFloat allowableMovement;指定该长按手势允许用户移动手指的最大距离,如果用户手指按下时移动超过了该距离,则长按手势失效.

实例:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    //创建一个NSMutableArray集合 用于保存过个按钮
    bnArray = [[NSMutableArray alloc]init];
    //创建一个手势处理器 用于检测.处理长按手势
    UILongPressGestureRecognizer* gesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
    //为该控件添加手势处理器
    [self.view addGestureRecognizer:gesture];
}
- (void)longPress:(UILongPressGestureRecognizer *)gesture{
    //创建一个按钮
    UIButton* bn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    //获取NSArray中已经包含了几个按钮
    NSInteger count = bnArray.count;
    //计算当前添加的按钮位于第几行第几列
    NSInteger row = count/3;
    NSInteger col = count%3;
    //为按钮设置文本
    [bn setTitle:[NSString stringWithFormat:@"按钮%ld",bnIndex] forState:UIControlStateNormal];
    //设置该bn按钮的大小和位置
    bn.frame = CGRectMake(MARGINE + col * CELL_WIDTH, row * CELL_HEIGHT + MARGINE, BUTTON_WIDTH, BUTTON_HEIHGT);
    //为该按钮添加事件处理方法
    [bn addTarget:self action:@selector(remove:) forControlEvents:UIControlEventTouchUpInside];
    [bnArray addObject:bn];
    //将按钮添加到应用界面的UIView控件中
    [self.view addSubview:bn];
    bnIndex ++;
}
- (void)remove:(id)sender{
    //删除事件源控件(激发该事件的按钮)
    [sender removeFromSuperview];
    //将触发该事件的按钮从NSMutableArray集合中删除
    [bnArray removeObject:sender];
    [self rearrange];
}
- (void)rearrange{
    //重新计算每个按钮的大小和位置
    for (int i = 0; i < bnArray.count ; i ++) {
        NSInteger row = i/3;
        NSInteger col = i%3;
        UIButton* bn = [bnArray objectAtIndex:i];
        bn.frame = CGRectMake(MARGINE +  col * CELL_WIDTH, row * CELL_HEIGHT + MARGINE, BUTTON_WIDTH, BUTTON_HEIHGT);
    }
}

四、创建和使用自定义手势处理器

1、开发自定义手势处理器

开发自定义手势处理器的步骤比较简单,按如下步骤操作即可:
①、创建继承UIGestureRecognizer的子类;
②、重写UIGestureRecognizer基类的触碰相关的4个方法.通过在这些方法中识别用户手指划过的痕迹—当用户手指划过的痕迹符合手势要求时,程序将该手势state设为UIGestureRecognizerStateEnaded即可.

2、使用自定义手势处理器

待定

五、手势互斥

手势识别是具有互斥的原则的,比如单击和双击,如果它识别出一种手势,其后的手势将不被识别。所以对于关联手势,要做特殊处理以帮助程序甄别,应该把当前手势归结到哪一类手势里面。

比如,单击和双击并存时,如果不做处理,它就只能发送出单击的消息。为了能够识别出双击手势,就需要做一个特殊处理逻辑,即先判断手势是否是双击,在双击失效的情况下作为单击手势处理。使用
[A requireGestureRecognizerToFail:B]函数,它可以指定当A手势发生时,即便A已经滿足条件了,也不会立刻触发,会等到指定的手势B确定失败之后才触发。

- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

//例如
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer]; 

六、UIGestureRecognizerDelegate

1、

// called when a gesture recognizer attempts to transition out of UIGestureRecognizerStatePossible. returning NO causes it to transition to UIGestureRecognizerStateFailed
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

手势可能发生的条件,比如某些特殊情况下,不想让此手势发生,就return NO。
2、

// called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
// return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
//
// note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

gestureRecognizer可能被otherGestureRecognizer手势识别引起阻塞,返回YES为允许同时识别。默认返回NO(默认情况下同一种手势只能识别一个)
3、

// called before touchesBegan:withEvent: is called on the gesture recognizer for a new touch. return NO to prevent the gesture recognizer from seeing this touch
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

方法touchesBegan:withEvent:执行前将调用该方法,返回YES执行手势事件;返回NO,将不响应手势事件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第一章:多点触摸与手势检测 的相关文章

  • 以管理员身份运行bat文件

    echo off gt nul 2 gt 1 SYSTEMROOT system32 cacls exe SYSTEMROOT system32 config system if errorlevel NEQ 0 goto UACPromp
  • 线性代数——矩阵1

    矩阵 Matrix 不要把矩阵放在分母上 矩阵的概念 有m n个数排成的m行n列的数表称为m行n列的矩阵 简称m n 记作 这m n个数称为矩阵A的元素 简称为元 数aij位于矩阵A的第i行第j列 称为矩阵A的 i j 元 以数 aij为
  • GIT常用统计

    查看git上个人代码量 git log author username pretty tformat numstat awk add 1 subs 2 loc 1 2 END printf added lines s removed lin
  • va_list 详解

    VA LIST 是在C语言中解决变参问题的一组宏 VA LIST的成员 1 va list型变量 ifdef M ALPHA typedef struct char a0 pointer to first homed integer arg
  • 【Spring 核心

    IoC IoC 简介 定义 IoC 和 DI Bean IoC 容器 Ioc IoC容器 IoC 简介 定义 IoC即控制反转 Inversion of Control 缩写为 IoC IoC又称为依赖倒置原则 设计模式六大原则之一 IoC
  • 技术文档工程师笔试_如何帮助工程师制作技术文档

    技术文档工程师笔试 As discussed in my previous post technical writers are a vital part of any team They focus on creating documen
  • FPGA计数器边界问题解析

    FPGA计数器边界问题解析 一次作者在处理AMBE2000数据接收过程中 遇到一个问题 对该计数器边界总是模糊不清 现在予以说明 以警示以后工作时书写错误代码 AMBE2000数据一旦准备好后 一次会输出24个字 其中第1个字0x13ec是

随机推荐

  • 数智人力时代,如何通过人才精细化管理发挥员工最大效能

    人才作为企业竞争中最活跃 也最有创造力的资源要素 管理他们同样也不得马虎 一刀切和单一维度地进行人才分类 不利于员工充分发挥主观能动性 进而提升组织能力 而要让员工在工作中有成就感 获得感和主动性 就需要进行人才精细化管理 对症下药 才能实
  • thinter打开新窗口隐藏主窗口并实现窗口切换

    from tkinter import windows Tk windows geometry 500x300 windows title 主窗口 def b windows withdraw 隐藏主窗口 global root root
  • 百度AI(一)

    前言 第一步 在百度AI上注册账号 在控制台内创建属于你的相应的应用 以下是创建完成后的 API Key SecretKey 是俩个要用到的参数 根据文档 选择相应的API 人脸对比请求地址 发送请求获取 access token 注意 a
  • keepalived + lvs (DR)

    目录 一 概念 二 实验流程命令 三 实验的目的 四 实验步骤 一 概念 Keepalived和LVS Linux Virtual Server 可以结合使用来实现双机热备和负载均衡 Keepalived负责监控主备服务器的可用性 并在主服
  • MySQL —— 复合查询

    目录 MySQL复合查询 一 基本查询回顾 二 多表查询 三 自连接 四 子查询 1 单行子查询 2 多行子查询 3 多列子查询 4 在from子句中使用子查询 五 合并查询 MySQL复合查询 一 基本查询回顾 前面我们讲解的mysql表
  • 2023年——个人每日分享汇总

    摘要 今年是每日分享的第四个年头 在这几年分享中 虽然回头看不知道当时分享内容由何而感 分享内容现在也遗忘记不住 但是这个过程中能够感觉到自己的一个改变 现在的内容错别字少了 也会检查一下语句是否通顺 修行 修心 成长 价值 学到一个四阶段
  • vue过滤器和修饰符

    过滤器的作用 在我们页面显示值之前加一层过滤 展示我们过滤后的值 注意事项 过滤器可以用在两个地方 双花括号插值和 v bind 表达式 使用语法 变量 过滤器名 1 全局定义 Vue filter gettime function dat
  • 百度墨卡托坐标转百度经纬度坐标Python

    本文参考 https blog csdn net qq 16664325 article details 67639684 原文用的是java语言 我只是把它转成Python语言 xu 6370996 81 Sp 1 289059486E7
  • shell脚本----if(数字条件,字符串条件,字符串为空)

    二元比较操作符 比较变量或者比较数字 注意数字与字符串的区别 1 整数比较 cpp view plain copy print eq 等于 如 if a eq b ne 不等于 如 if a ne b gt 大于 如 if a gt b g
  • plt.rcParams参数详解

    plt rcParams参数详解 0 plt rcParams参数 1 Font 1 1 字体 1 2 样式 新增 0 plt rcParams参数 plt rcParams keys font 1 Font 1 1 字体 plt rcPa
  • 数字化时代-20:一张图看清中国金融市场的轮廓

    关键词 资本 金钱 金融 银行 证券 保险 财政 中国制度优势 前言 本文试图通过图解的方式 从宏观上对中国的金融市场有一个初步的认识 在金融市场上流动的鲜血是金钱 金钱是金融市场 甚至整个经济的血液 金钱的充沛的流动给整个经济注入活力 金
  • 蓝桥杯 ADV-319 VIP试题 哈密尔顿回路(试题解析)

    试题 算法提高 哈密尔顿回路 提交此题 评测记录 资源限制 时间限制 2 0s 内存限制 256 0MB 问题描述 给出一个有向图 输出这个图的一个哈密尔顿回路 输入格式 输入的第一行包含两个整数n m 分别表示图的点数和边数 接下来m行
  • Java基础-实现zip解压缩

    可实现 文件 文件夹的解压缩操作 import java io File import java io FileInputStream import java io FileOutputStream import java io IOExc
  • Flutter控件——常用控件:Text

    Text text dart 源码 const Text String this data 要显示的字符串 Key key this style 样式TextStyle this strutStyle this textAlign 文本应如
  • 【C++】IO流

    文章目录 1 自定义类型与内置类型的相互转化 1 1operator 类型 2 C 文件IO 3 C 文件IO的二进制读取和文本读取 4 stringstream 类 1 自定义类型与内置类型的相互转化 在做IO类型的OJ的时候 有多个接收
  • 代码潜在故障的动态分析

    b size large 引子 size b 大家都听说过FindBugs的大名 这是一款静态代码分析的工具 能够直接对字节码文件加以分析 并发现潜在的反模式 anti pattern 从而有效地促进代码质量的改善 但FindBugs只能用
  • 核密度估计 Kernel density estimation

    简单贝叶斯分类 对于数值属性 如果不服从正态分布 但不知道服从何种分布形式 可以采用核密度估计的方法来进行预测 1 from http baike baidu com view 3380594 htm kernel density esti
  • windows常用命令

    1 打开控制台命令窗口 Win R 2 文件 目录 cd 切换目录 例 cd 显示当前目录 例 cd 进入父目录 例 cd d d 进入上次d盘所在的目录 或在直接输入 d 例 cd d d 进入d盘根目录 例 cd d 显示上次d盘所在的
  • C/C++中二级指针传递参数【个人遇到内存值发生改变现象的记录及相关修正方法】

    目录 0 前言 1 二级指针传参奇怪现象 2 分析 3 解决方法 0 前言 在c c 中 时常会使用到主调函数通过参数去获取被调函数中的数值情况 针对这种情况 我前面也写过C C 主调函数从被调函数中获取 各种类型 数据内容方式的梳理归纳文
  • 第一章:多点触摸与手势检测

    一 响应者链 只要继承了UIResponder的对象就可作为事件的响应者 实际上UIControl继承了UIView UIView又继承了UIResponder 由此可见 所有的对象都可作为事件的响应者 当用户与某个控件交互时 该控件将作为