1、UIGestureRecognizer 介绍

手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性。

iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureRecognizer 的子类),开发者可以直接使用他们进行手势操作。

  • UIPanGestureRecognizer(拖动)

  • UIPinchGestureRecognizer(捏合)

  • UIRotationGestureRecognizer(旋转)

  • UITapGestureRecognizer(点按)

  • UILongPressGestureRecognizer(长按)

  • ​UISwipeGestureRecognizer(轻扫)

另外,可以通过继承 UIGestureRecognizer 类,实现自定义手势(手势识别器类)。

PS:自定义手势时,需要 #import <UIKit/UIGestureRecognizerSubclass.h>,一般需实现如下方法:

1 - (void)reset;
2
3 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
4 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
5 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
6 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
7 //以上方法在分类 UIGestureRecognizer (UIGestureRecognizerProtected) 中声明,更多方法声明请自行查看

UIGestureRecognizer 的继承关系如下:

2、手势状态

在六种手势识别中,只有一种手势是离散型手势,他就是 UITapGestureRecognizer。

离散型手势的特点就是:一旦识别就无法取消,而且只会调用一次手势操作事件(初始化手势时指定的回调方法)。

​换句话说其他五种手势是连续型手势,而连续型手势的特点就是:会多次调用手势操作事件,而且在连续手势识别后可以取消手势。从下图可以看出两者调用操作事件的次数是不同的:

手势状态枚举如下:

1 typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
2 UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
3 UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
4 UIGestureRecognizerStateChanged, // 手势状态发生转变
5 UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
6 UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
7 UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
8 UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
9 };
  • 对于离散型手势 UITapGestureRecgnizer 要么被识别,要么失败,点按(假设点按次数设置为1,并且没有添加长按手势)下去一次不松开则此时什么也不会发生,松开手指立即识别并调用操作事件,并且状态为3(已完成)。
  • 但是连续型手势要复杂一些,就拿旋转手势来说,如果两个手指点下去不做任何操作,此时并不能识别手势(因为我们还没旋转)但是其实已经触发了触摸开始事件,此时处于状态0;如果此时旋转会被识别,也就会调用对应的操作事件,同时状态变成1(手势开始),但是状态1只有一瞬间;紧接着状态变为2(因为我们的旋转需要持续一会),并且重复调用操作事件(如果在事件中打印状态会重复打印2);松开手指,此时状态变为3,并调用1次操作事件。

3、使用手势的步骤

使用手势很简单,分为三步:

  1. 创建手势识别器对象实例。创建时,指定一个回调方法,当手势开始,改变、或结束时,执行回调方法。

  2. 设置手势识别器对象实例的相关属性(可选部分)

  3. 添加到需要识别的 View 中。每个手势只对应一个 View,当屏幕触摸在 View 的边界内时,如果手势和预定的一样,那就会执行回调方法。

PS:一个手势只能对应一个 View,但是一个 View 可以有多个手势。建议在真机上测试这些手势,模拟器操作不太方便,可能导致认为手势失效的情况。(模拟器测试捏合和旋转手势时,按住 option 键,再用触摸板或鼠标操作)

4、举例说明

功能描述:

附加到两个图片视图 UIImageView 的有『拖动』、『捏合』、『旋转』、『点按』;

而『轻扫』和『自定义手势 KMGestureRecognizer』附加在根视图 UIView 中。

  1. 拖动:进行当前图片视图位置移动

  2. 捏合:进行当前图片视图缩放

  3. 旋转:进行当前图片视图角度旋转

  4. 点按:双击恢复当前图片视图的缩放、角度旋转、不透明度

  5. 长按:设置当前图片视图的不透明度为0.7

  6. 轻扫:左右轻扫设置两个图片视图为居中,同时以垂直居中的特定偏移量定位

  7. 自定义手势:挠痒功能,左右扫动共3次或以上,设置两个图片视图为居中,同时以水平居中的特定偏移量定位

效果如下:

KMGestureRecognizer.h

 1 #import <UIKit/UIKit.h>
2
3 typedef NS_ENUM(NSUInteger, Direction) {
4 DirectionUnknown,
5 DirectionLeft,
6 DirectionRight
7 };
8
9 @interface KMGestureRecognizer : UIGestureRecognizer
10 @property (assign, nonatomic) NSUInteger tickleCount; //挠痒次数
11 @property (assign, nonatomic) CGPoint currentTickleStart; //当前挠痒开始坐标位置
12 @property (assign, nonatomic) Direction lastDirection; //最后一次挠痒方向
13
14 @end

KMGestureRecognizer.m

 1 #import "KMGestureRecognizer.h"
2 #import <UIKit/UIGestureRecognizerSubclass.h>
3
4 @implementation KMGestureRecognizer
5 #define kMinTickleSpacing 20.0
6 #define kMaxTickleCount 3
7
8 - (void)reset {
9 _tickleCount = 0;
10 _currentTickleStart = CGPointZero;
11 _lastDirection = DirectionUnknown;
12
13 if (self.state == UIGestureRecognizerStatePossible) {
14 self.state = UIGestureRecognizerStateFailed;
15 }
16 }
17
18 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
19 UITouch *touch = [touches anyObject];
20 _currentTickleStart = [touch locationInView:self.view]; //设置当前挠痒开始坐标位置
21 }
22
23 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
24 //『当前挠痒开始坐标位置』和『移动后坐标位置』进行 X 轴值比较,得到是向左还是向右移动
25 UITouch *touch = [touches anyObject];
26 CGPoint tickleEnd = [touch locationInView:self.view];
27 CGFloat tickleSpacing = tickleEnd.x - _currentTickleStart.x;
28 Direction currentDirection = tickleSpacing < 0 ? DirectionLeft : DirectionRight;
29
30 //移动的 X 轴间距值是否符合要求,足够大
31 if (ABS(tickleSpacing) >= kMinTickleSpacing) {
32 //判断是否有三次不同方向的动作,如果有则手势结束,将执行回调方法
33 if (_lastDirection == DirectionUnknown ||
34 (_lastDirection == DirectionLeft && currentDirection == DirectionRight) ||
35 (_lastDirection == DirectionRight && currentDirection == DirectionLeft)) {
36 _tickleCount++;
37 _currentTickleStart = tickleEnd;
38 _lastDirection = currentDirection;
39
40 if (_tickleCount >= kMaxTickleCount && self.state == UIGestureRecognizerStatePossible) {
41 self.state = UIGestureRecognizerStateEnded;
42 //NSLog(@"自定义手势成功,将执行回调方法");
43 }
44 }
45 }
46 }
47
48 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
49 [self reset];
50 }
51
52 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
53 [self reset];
54 }
55
56 @end

ViewController.h

1 #import <UIKit/UIKit.h>
2 #import "KMGestureRecognizer.h"
3
4 @interface ViewController : UIViewController
5 @property (strong, nonatomic) UIImageView *imgV;
6 @property (strong, nonatomic) UIImageView *imgV2;
7 @property (strong, nonatomic) KMGestureRecognizer *customGestureRecognizer;
8
9 @end

ViewController.m

  1 #import "ViewController.h"
2
3 @interface ViewController ()
4 - (void)handlePan:(UIPanGestureRecognizer *)recognizer;
5 - (void)handlePinch:(UIPinchGestureRecognizer *)recognizer;
6 - (void)handleRotation:(UIRotationGestureRecognizer *)recognizer;
7 - (void)handleTap:(UITapGestureRecognizer *)recognizer;
8 - (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer;
9 - (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer;
10 - (void)handleCustomGestureRecognizer:(KMGestureRecognizer *)recognizer;
11
12 - (void)bindPan:(UIImageView *)imgVCustom;
13 - (void)bindPinch:(UIImageView *)imgVCustom;
14 - (void)bindRotation:(UIImageView *)imgVCustom;
15 - (void)bindTap:(UIImageView *)imgVCustom;
16 - (void)bindLongPress:(UIImageView *)imgVCustom;
17 - (void)bindSwipe;
18 - (void)bingCustomGestureRecognizer;
19 - (void)layoutUI;
20 @end
21
22 @implementation ViewController
23
24 - (void)viewDidLoad {
25 [super viewDidLoad];
26
27 [self layoutUI];
28 }
29
30 - (void)didReceiveMemoryWarning {
31 [super didReceiveMemoryWarning];
32 // Dispose of any resources that can be recreated.
33 }
34
35 #pragma mark - 处理手势操作
36 /**
37 * 处理拖动手势
38 *
39 * @param recognizer 拖动手势识别器对象实例
40 */
41 - (void)handlePan:(UIPanGestureRecognizer *)recognizer {
42 //视图前置操作
43 [recognizer.view.superview bringSubviewToFront:recognizer.view];
44
45 CGPoint center = recognizer.view.center;
46 CGFloat cornerRadius = recognizer.view.frame.size.width / 2;
47 CGPoint translation = [recognizer translationInView:self.view];
48 //NSLog(@"%@", NSStringFromCGPoint(translation));
49 recognizer.view.center = CGPointMake(center.x + translation.x, center.y + translation.y);
50 [recognizer setTranslation:CGPointZero inView:self.view];
51
52 if (recognizer.state == UIGestureRecognizerStateEnded) {
53 //计算速度向量的长度,当他小于200时,滑行会很短
54 CGPoint velocity = [recognizer velocityInView:self.view];
55 CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
56 CGFloat slideMult = magnitude / 200;
57 //NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); //e.g. 397.973175, slideMult: 1.989866
58
59 //基于速度和速度因素计算一个终点
60 float slideFactor = 0.1 * slideMult;
61 CGPoint finalPoint = CGPointMake(center.x + (velocity.x * slideFactor),
62 center.y + (velocity.y * slideFactor));
63 //限制最小[cornerRadius]和最大边界值[self.view.bounds.size.width - cornerRadius],以免拖动出屏幕界限
64 finalPoint.x = MIN(MAX(finalPoint.x, cornerRadius),
65 self.view.bounds.size.width - cornerRadius);
66 finalPoint.y = MIN(MAX(finalPoint.y, cornerRadius),
67 self.view.bounds.size.height - cornerRadius);
68
69 //使用 UIView 动画使 view 滑行到终点
70 [UIView animateWithDuration:slideFactor*2
71 delay:0
72 options:UIViewAnimationOptionCurveEaseOut
73 animations:^{
74 recognizer.view.center = finalPoint;
75 }
76 completion:nil];
77 }
78 }
79
80 /**
81 * 处理捏合手势
82 *
83 * @param recognizer 捏合手势识别器对象实例
84 */
85 - (void)handlePinch:(UIPinchGestureRecognizer *)recognizer {
86 CGFloat scale = recognizer.scale;
87 recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, scale, scale); //在已缩放大小基础下进行累加变化;区别于:使用 CGAffineTransformMakeScale 方法就是在原大小基础下进行变化
88 recognizer.scale = 1.0;
89 }
90
91 /**
92 * 处理旋转手势
93 *
94 * @param recognizer 旋转手势识别器对象实例
95 */
96 - (void)handleRotation:(UIRotationGestureRecognizer *)recognizer {
97 recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
98 recognizer.rotation = 0.0;
99 }
100
101 /**
102 * 处理点按手势
103 *
104 * @param recognizer 点按手势识别器对象实例
105 */
106 - (void)handleTap:(UITapGestureRecognizer *)recognizer {
107 UIView *view = recognizer.view;
108 view.transform = CGAffineTransformMakeScale(1.0, 1.0);
109 view.transform = CGAffineTransformMakeRotation(0.0);
110 view.alpha = 1.0;
111 }
112
113 /**
114 * 处理长按手势
115 *
116 * @param recognizer 点按手势识别器对象实例
117 */
118 - (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer {
119 //长按的时候,设置不透明度为0.7
120 recognizer.view.alpha = 0.7;
121 }
122
123 /**
124 * 处理轻扫手势
125 *
126 * @param recognizer 轻扫手势识别器对象实例
127 */
128 - (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer {
129 //代码块方式封装操作方法
130 void (^positionOperation)() = ^() {
131 CGPoint newPoint = recognizer.view.center;
132 newPoint.y -= 20.0;
133 _imgV.center = newPoint;
134
135 newPoint.y += 40.0;
136 _imgV2.center = newPoint;
137 };
138
139 //根据轻扫方向,进行不同控制
140 switch (recognizer.direction) {
141 case UISwipeGestureRecognizerDirectionRight: {
142 positionOperation();
143 break;
144 }
145 case UISwipeGestureRecognizerDirectionLeft: {
146 positionOperation();
147 break;
148 }
149 case UISwipeGestureRecognizerDirectionUp: {
150 break;
151 }
152 case UISwipeGestureRecognizerDirectionDown: {
153 break;
154 }
155 }
156 }
157
158 /**
159 * 处理自定义手势
160 *
161 * @param recognizer 自定义手势识别器对象实例
162 */
163 - (void)handleCustomGestureRecognizer:(KMGestureRecognizer *)recognizer {
164 //代码块方式封装操作方法
165 void (^positionOperation)() = ^() {
166 CGPoint newPoint = recognizer.view.center;
167 newPoint.x -= 20.0;
168 _imgV.center = newPoint;
169
170 newPoint.x += 40.0;
171 _imgV2.center = newPoint;
172 };
173
174 positionOperation();
175 }
176
177
178 #pragma mark - 绑定手势操作
179 /**
180 * 绑定拖动手势
181 *
182 * @param imgVCustom 绑定到图片视图对象实例
183 */
184 - (void)bindPan:(UIImageView *)imgVCustom {
185 UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
186 action:@selector(handlePan:)];
187 [imgVCustom addGestureRecognizer:recognizer];
188 }
189
190 /**
191 * 绑定捏合手势
192 *
193 * @param imgVCustom 绑定到图片视图对象实例
194 */
195 - (void)bindPinch:(UIImageView *)imgVCustom {
196 UIPinchGestureRecognizer *recognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self
197 action:@selector(handlePinch:)];
198 [imgVCustom addGestureRecognizer:recognizer];
199 //[recognizer requireGestureRecognizerToFail:imgVCustom.gestureRecognizers.firstObject];
200 }
201
202 /**
203 * 绑定旋转手势
204 *
205 * @param imgVCustom 绑定到图片视图对象实例
206 */
207 - (void)bindRotation:(UIImageView *)imgVCustom {
208 UIRotationGestureRecognizer *recognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self
209 action:@selector(handleRotation:)];
210 [imgVCustom addGestureRecognizer:recognizer];
211 }
212
213 /**
214 * 绑定点按手势
215 *
216 * @param imgVCustom 绑定到图片视图对象实例
217 */
218 - (void)bindTap:(UIImageView *)imgVCustom {
219 UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
220 action:@selector(handleTap:)];
221 //使用一根手指双击时,才触发点按手势识别器
222 recognizer.numberOfTapsRequired = 2;
223 recognizer.numberOfTouchesRequired = 1;
224 [imgVCustom addGestureRecognizer:recognizer];
225 }
226
227 /**
228 * 绑定长按手势
229 *
230 * @param imgVCustom 绑定到图片视图对象实例
231 */
232 - (void)bindLongPress:(UIImageView *)imgVCustom {
233 UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
234 recognizer.minimumPressDuration = 0.5; //设置最小长按时间;默认为0.5秒
235 [imgVCustom addGestureRecognizer:recognizer];
236 }
237
238 /**
239 * 绑定轻扫手势;支持四个方向的轻扫,但是不同的方向要分别定义轻扫手势
240 */
241 - (void)bindSwipe {
242 //向右轻扫手势
243 UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
244 action:@selector(handleSwipe:)];
245 recognizer.direction = UISwipeGestureRecognizerDirectionRight; //设置轻扫方向;默认是 UISwipeGestureRecognizerDirectionRight,即向右轻扫
246 [self.view addGestureRecognizer:recognizer];
247 [recognizer requireGestureRecognizerToFail:_customGestureRecognizer]; //设置以自定义挠痒手势优先识别
248
249 //向左轻扫手势
250 recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
251 action:@selector(handleSwipe:)];
252 recognizer.direction = UISwipeGestureRecognizerDirectionLeft;
253 [self.view addGestureRecognizer:recognizer];
254 [recognizer requireGestureRecognizerToFail:_customGestureRecognizer]; //设置以自定义挠痒手势优先识别
255 }
256
257 /**
258 * 绑定自定义挠痒手势;判断是否有三次不同方向的动作,如果有则手势结束,将执行回调方法
259 */
260 - (void)bingCustomGestureRecognizer {
261 //当 recognizer.state 为 UIGestureRecognizerStateEnded 时,才执行回调方法 handleCustomGestureRecognizer:
262
263 //_customGestureRecognizer = [KMGestureRecognizer new];
264 _customGestureRecognizer = [[KMGestureRecognizer alloc] initWithTarget:self
265 action:@selector(handleCustomGestureRecognizer:)];
266 [self.view addGestureRecognizer:_customGestureRecognizer];
267 }
268
269 - (void)layoutUI {
270 //图片视图 _imgV
271 UIImage *img = [UIImage imageNamed:@"Emoticon_tusiji_icon"];
272 CGFloat cornerRadius = img.size.width;
273 _imgV = [[UIImageView alloc] initWithImage:img];
274 _imgV.frame = CGRectMake(20.0, 20.0,
275 cornerRadius * 2, cornerRadius * 2);
276 _imgV.userInteractionEnabled = YES;
277 _imgV.layer.masksToBounds = YES;
278 _imgV.layer.cornerRadius = cornerRadius;
279 _imgV.layer.borderWidth = 2.0;
280 _imgV.layer.borderColor = [UIColor grayColor].CGColor;
281 [self.view addSubview:_imgV];
282
283 //图片视图 _imgV2
284 img = [UIImage imageNamed:@"Emoticon_tusiji_icon2"];
285 cornerRadius = img.size.width;
286 _imgV2 = [[UIImageView alloc] initWithImage:img];
287 _imgV2.frame = CGRectMake(20.0, 40.0 + _imgV.frame.size.height,
288 cornerRadius * 2, cornerRadius * 2);
289 _imgV2.userInteractionEnabled = YES;
290 _imgV2.layer.masksToBounds = YES;
291 _imgV2.layer.cornerRadius = cornerRadius;
292 _imgV2.layer.borderWidth = 2.0;
293 _imgV2.layer.borderColor = [UIColor orangeColor].CGColor;
294 [self.view addSubview:_imgV2];
295
296
297 [self bindPan:_imgV];
298 [self bindPinch:_imgV];
299 [self bindRotation:_imgV];
300 [self bindTap:_imgV];
301 [self bindLongPress:_imgV];
302
303 [self bindPan:_imgV2];
304 [self bindPinch:_imgV2];
305 [self bindRotation:_imgV2];
306 [self bindTap:_imgV2];
307 [self bindLongPress:_imgV2];
308
309 //为了处理手势识别优先级的问题,这里需先绑定自定义挠痒手势
310 [self bingCustomGestureRecognizer];
311 [self bindSwipe];
312 }
313
314 @end

iOS手势操作,拖动,轻击,捏合,旋转,长按,自定义(http://www.cnblogs.com/huangjianwu/p/4675648.html)的更多相关文章

  1. UI中各种手势的使用点击,捏合,清扫,旋转,平移,边缘移动,长按

    #import "RootViewController.h" @interface RootViewController (){    UIImageView *imageView ...

  2. ios手势操作,四个基本事件与六个常用事件

    基本事件包括begin,canceled,move,ended四项,如果对象的hidden属性为yes,则无效果,hidden属性必须为no;才能使用: -(void)touchesBegan:(NS ...

  3. iOS 手势操作:拖动、捏合、旋转、点按、长按、轻扫、自定义

    1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...

  4. ios手势

    iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小   1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...

  5. iOS 手势识别器概述

    手势识别器 iOS 手势识别器(UIGestureRecognizer) 点击手势(UITapGestureRecognizer) 滑动手势(UISwipeGestureRecognizer) 旋转手 ...

  6. iOS--------手势识别的详细使用:拖动、缩放、旋转、点击、手势依赖、自定义手势

    1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了 ...

  7. iOS 轻击、触摸和手势的检测

    一.检测捏合手势( UIPinchGestureRecognizer):  //设定一个实例变量存储手指之间的其起始距离 @property (assign, nonatomic) CGFloat i ...

  8. ios的手势操作之UIGestureRecognizer浅析

    转载地址:http://blog.csdn.net/likendsl/article/details/7554150 每一个手势的实现例子,可参考下面网址:http://www.cnblogs.com ...

  9. 【转】 ios的手势操作之UIGestureRecognizer浅析

    一.概述 iPhone中处理触摸屏的操作,在3.2之前是主要使用的是由UIResponder而来的如下4种方式: - (void)touchesBegan:(NSSet *)touches withE ...

随机推荐

  1. Linux基本命令使用(三)

    1.压缩解压命令:gzip,   .gz格式的 gzip 文件名     就压缩了. Linux压缩的放到Windows下可以解压,但是Windows下压缩到Linux解压就不一定可以. (1)只能压 ...

  2. pycharm 安装激活

    下载pycharm :http://www.jetbrains.com/pycharm/download/download 安装 直到 finish 下载补丁jetbrains-agent.jar并添 ...

  3. MapReduce数据倾斜的解决方式

    数据倾斜:由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点.map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时 ...

  4. 第五周课程总结&试验报告

    this和super的区别 区别点 this super 属性访问 访问同类中的属性,如果本类没有此属性则从父类中继续查找 访问父类中的属性 方法 访问本类中的方法,如果本类中没有此方法,则从父类中继 ...

  5. layer系列之table导出+打印功能总结

    1.关于layui导出方式,直接使用layui(版本2.4.5及以上)自带的导出方法即可: layui官网地址:https://www.layui.com/ 源码如下: <!DOCTYPE ht ...

  6. maven 安装jar包命令

    以 spring-context-support-3.1.0.RELEASE.jar 为例,在 @3图中已经给出这个 jar 包的 groupId,artifactId,version信息,手动安装的 ...

  7. 分布式任务队列 Celery —— 应用基础

    目录 目录 前文列表 前言 Celery 的周期定时任务 Celery 的同步调用 Celery 结果储存 Celery 的监控 Celery 的调试 前文列表 分布式任务队列 Celery 分布式任 ...

  8. Text Elements(文本元素)对象

    1.T-Code:SE32 操作路径:主菜单——转到——内文元素——选择内文 2. 清单标题(List heading) 用于定义Report标题名称及描述,如图: 2. 選擇內文 (Selectio ...

  9. PHP开发一个简单的成绩录入系统

    预览界面 源码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  10. python 并发编程 多进程 模拟抢票

    抢票是并发执行 多个进程可以访问同一个文件 多个进程共享同一文件,我们可以把文件当数据库,用多个进程模拟多个人执行抢票任务 db.txt {"count": 1} 并发运行,效率高 ...