實現效果:小窗口拖動,注意是僅當拖動小窗口時候才移動,觸摸小窗口外部不移動
hitTest: 方法同樣接受一個CGPoint類型參數,而不是BOOL類型,它返回圖層本身,或者包含這個坐標點的葉子節點圖層。直接獲得位于點擊事件響應鏈條最前沿的子圖層或自身,不需要一層一層用-conrainsPoint:去判斷
如果說小窗口視圖沒有非常復雜的視圖的結構的話,采用以下的方法
觸摸事件開始,主要做點擊區域判斷
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
CALayer *touchedLayer = [self.view.layer hitTest:point];
if(touchedLayer == self.smallView.layer){
self.isMoving = YES;
}
}
拖動過程,計算偏移
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesMoved:touches withEvent:event];
if(!self.isMoving){
return;
}
UITouch *touch = [touches anyObject];
CGPoint current = [touch locationInView:self.view];
CGPoint previous = [touch previousLocationInView:self.view];
CGPoint center = self.smallView.center;
CGPoint offset = CGPointMake(current.x - previous.x, current.y - previous.y);
self.smallView.center = CGPointMake(center.x + offset.x, center.y + offset.y);
}
拖動結束
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesEnded:touches withEvent:event];
self.isMoving = NO;
}
相對而言的,如果說小窗口有比較復雜的視圖結構,比如說有多級子視圖,這時候上面的方法久不合適了
原因:-touchesBegan:方法中CALayer *touchedLayer = [self.view.layer hitTest:point];
會直接獲取頂層的圖層,也就是位于響應鏈最前沿的視圖的圖層,所以這時候再進行圖層判斷if(touchedLayer == self.smallView.layer){
就不合適了!
-containsPoint:
接受一個在本圖層坐標系下的CGPoint,如果這個點在圖層frame范圍內就返回YES
這時候就就應該采用如下的方式
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
//Converts the point from the specified layer’s coordinate system to the receiver’s coordinate system.
point = [self.catEarView.layer convertPoint:point fromLayer:self.view.layer];
if([self.catEarView.layer containsPoint:point]){
self.isMoving = YES;
}
}