首先簡(jiǎn)單介紹一下UITouch吧!
屬相與方法:
- window:觸摸產(chǎn)生時(shí)所處的窗口。由于窗口可能發(fā)生變化,當(dāng)前所在的窗口不一定是最開(kāi)始的窗口。
- view:觸摸產(chǎn)生時(shí)所處的視圖。由于視圖可能發(fā)生變化,當(dāng)前視圖也不一定時(shí)最初的視圖。
- tapCount:輕擊(Tap)操作和鼠標(biāo)的單擊操作類(lèi)似,tapCount表示短時(shí)間內(nèi)輕擊屏幕的次數(shù)。因此可以根據(jù)tapCount判斷單擊、雙擊或更多的輕擊。
- timestamp: 時(shí)間戳記錄了觸摸事件產(chǎn)生或變化時(shí)的時(shí)間。單位是秒。
- phase:觸摸事件在屏幕上有一個(gè)周期,即觸摸開(kāi)始、觸摸點(diǎn)移動(dòng)、觸摸結(jié)束,還有中途取消。通過(guò)phase可以查看當(dāng)前觸摸事件在一個(gè)周期中所處的狀態(tài);
- phase是UITouchPhase類(lèi)型的,包括:
typedef NS_ENUM(NSInteger, UITouchPhase) {
UITouchPhaseBegan, (開(kāi)始) // whenever a finger touches the surface.
UITouchPhaseMoved, (移動(dòng)) // whenever a finger moves on the surface.
UITouchPhaseStationary, (無(wú)移動(dòng)) // whenever a finger is touching the surface but hasn't moved since the previous event.
UITouchPhaseEnded, (結(jié)束) // whenever a finger leaves the surface.
UITouchPhaseCancelled, (取消) // whenever a touch doesn't end but we need to stop tracking (e.g. putting device to face)
};
(CGPoint)locationInView:(UIView *)view:函數(shù)返回一個(gè)CGPoint類(lèi)型的值,表示觸摸在view這個(gè)視圖上的位置,這里返回的位置是針對(duì)view的坐標(biāo)系的。調(diào)用時(shí)傳入的view參數(shù)為空的話,返回的時(shí)觸摸點(diǎn)在整個(gè)窗口的位置。
(CGPoint)previousLocationInView:(UIView *)view:該方法記錄了前一個(gè)坐標(biāo)值,函數(shù)返回也是一個(gè)CGPoint類(lèi)型的值, 表示觸摸在view這個(gè)視圖上的位置,這里返回的位置是針對(duì)view的坐標(biāo)系的。調(diào)用時(shí)傳入的view參數(shù)為空的話,返回的時(shí)觸摸點(diǎn)在整個(gè)窗口的位置。
如何繪圖:
- 首先在- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 方法里添加曲線的起點(diǎn);
UITouch *touch = [touches anyObject];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, [touch locationInView:self].x, [touch locationInView:self].y);
[self.totalPathPoints addObject:(__bridge_transfer id)path];
可以不使用CGMutablePathRef,可以用數(shù)組然后再將self.totalPathPoints這個(gè)數(shù)組存在一個(gè)一個(gè)的小數(shù)組;然后遍歷也可以,方法有很多種;
__bridge_transfer 讓非Objective-C對(duì)象轉(zhuǎn)換為Objective-C對(duì)象
- 然后在- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event與- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event兩個(gè)方法里添加移動(dòng)的路徑;
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self drawLineWithTouches:touches];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self drawLineWithTouches:touches];
}
-(void)drawLineWithTouches:(NSSet *)touches {
UITouch *touch = [touches anyObject];
CGMutablePathRef path = (__bridge_retained CGMutablePathRef)self.totalPathPoints.lastObject;
CGPathAddLineToPoint(path, nil, [touch locationInView:self].x, [touch locationInView:self].y);
[self setNeedsDisplay];
}
注意:用[self setNeedsDisplay]調(diào)用- (void)drawRect:(CGRect)rect才有效;不可以手動(dòng)直接調(diào)用。
-(void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
for (id path in self.totalPathPoints) {
CGMutablePathRef ref = (__bridge_retained CGMutablePathRef)path;
CGContextAddPath(context, ref);
}
// 線段的寬度
CGContextSetLineWidth(context, 5);
[[UIColor blackColor] setStroke];
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextStrokePath(context);
}
__bridge_retained 是將Objective-C對(duì)象轉(zhuǎn)換為非Objective-C對(duì)象;Objective-C 和 Core Foundation 對(duì)象之間可以輕松的轉(zhuǎn)換

效果圖