在 UIView Mask 中限制 UIPanGestureRecognizer
restrict UIPanGestureRecognizer in UIView Mask
我使用 UIBezierPath 将 UIView(240 * 240) 屏蔽成三角形,如下所示:
path = [UIBezierPath new];
[path moveToPoint:(CGPoint){0, 240}];
[path addLineToPoint:(CGPoint){120,0}];
[path addLineToPoint:(CGPoint){240,240}];
[path addLineToPoint:(CGPoint){0,240}];
[path closePath];
CAShapeLayer *mask = [CAShapeLayer new];
mask.frame = self.viewShape.bounds;
mask.path = path.CGPath;
self.viewShape.layer.mask = mask;
上图三角形区域为遮罩。现在我有了 "Coca-Cola" 的图像,它只能在三角形蒙版中移动。因此,为此我已将 UIPanGestureRecognizer 应用到 UIIMageView 并按以下方式限制其框架。
- (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint touchLocation = [gestureRecognizer locationInView:self.viewShape];
CGRect boundsRect;
BOOL isInside = [path containsPoint:CGPointMake(self.innerView.center.x, self.innerView.center.y)];
NSLog(@"value:%d",isInside);
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
}else{
NSLog(@"outside");
}
}
我上面的 if 条件执行成功但是当控制进入 else 条件时我无法将我的 ImageView 拖回掩码框架内.
所以,我的问题是当调用 else block(outside) 时,我应该能够再次将 imageView 拖到 Mask 的框架内。
我怎样才能做到这一点?
保存对图像视图最后一个中心的引用是实现此目的的一种方法。
在您的自定义视图中;
CGPoint lastValidCenter; //initially it is the center of imageview;
在代码中
NSLog(@"value:%d",isInside);
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
lastValidCenter = self.innerView.center;
}else{
NSLog(@"outside");
self.innerView.center = lastValidCenter;
}
你的计算有问题。您需要做的是检查 UIImageView
的左上角和右上角是否包含带有 UIBezirePath
实例的点。
之所以如此,是因为当图像移动时,这两个角都会首先尝试出去。所以只需检查一下,你就会得到你想要的输出。
BOOL isInside = [path containsPoint:CGPointMake(CGRectGetMinX(self.innerView.bounds), CGRectGetMinY(self.innerView.bounds))];
isInside = isInside || [path containsPoint:CGPointMake(CGRectGetMaxX(self.innerView.bounds), CGRectGetMinY(self.innerView.bounds))];
if (isInside) {
//Move your UIImageView
}
else {
//Don't move
}
我修改了 Meth 的部分代码。代码如下:
self.innerView.center = touchLocation;
BOOL isInside = [path containsPoint:CGPointMake(self.innerView.center.x, self.innerView.center.y)];
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
lastValidCenter = self.innerView.center;
}else{
NSLog(@"outside");
self.innerView.center = lastValidCenter;
}
我使用 UIBezierPath 将 UIView(240 * 240) 屏蔽成三角形,如下所示:
path = [UIBezierPath new];
[path moveToPoint:(CGPoint){0, 240}];
[path addLineToPoint:(CGPoint){120,0}];
[path addLineToPoint:(CGPoint){240,240}];
[path addLineToPoint:(CGPoint){0,240}];
[path closePath];
CAShapeLayer *mask = [CAShapeLayer new];
mask.frame = self.viewShape.bounds;
mask.path = path.CGPath;
self.viewShape.layer.mask = mask;
上图三角形区域为遮罩。现在我有了 "Coca-Cola" 的图像,它只能在三角形蒙版中移动。因此,为此我已将 UIPanGestureRecognizer 应用到 UIIMageView 并按以下方式限制其框架。
- (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint touchLocation = [gestureRecognizer locationInView:self.viewShape];
CGRect boundsRect;
BOOL isInside = [path containsPoint:CGPointMake(self.innerView.center.x, self.innerView.center.y)];
NSLog(@"value:%d",isInside);
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
}else{
NSLog(@"outside");
}
}
我上面的 if 条件执行成功但是当控制进入 else 条件时我无法将我的 ImageView 拖回掩码框架内.
所以,我的问题是当调用 else block(outside) 时,我应该能够再次将 imageView 拖到 Mask 的框架内。
我怎样才能做到这一点?
保存对图像视图最后一个中心的引用是实现此目的的一种方法。 在您的自定义视图中;
CGPoint lastValidCenter; //initially it is the center of imageview;
在代码中
NSLog(@"value:%d",isInside);
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
lastValidCenter = self.innerView.center;
}else{
NSLog(@"outside");
self.innerView.center = lastValidCenter;
}
你的计算有问题。您需要做的是检查 UIImageView
的左上角和右上角是否包含带有 UIBezirePath
实例的点。
之所以如此,是因为当图像移动时,这两个角都会首先尝试出去。所以只需检查一下,你就会得到你想要的输出。
BOOL isInside = [path containsPoint:CGPointMake(CGRectGetMinX(self.innerView.bounds), CGRectGetMinY(self.innerView.bounds))];
isInside = isInside || [path containsPoint:CGPointMake(CGRectGetMaxX(self.innerView.bounds), CGRectGetMinY(self.innerView.bounds))];
if (isInside) {
//Move your UIImageView
}
else {
//Don't move
}
我修改了 Meth 的部分代码。代码如下:
self.innerView.center = touchLocation;
BOOL isInside = [path containsPoint:CGPointMake(self.innerView.center.x, self.innerView.center.y)];
if (isInside) {
NSLog(@"inside");
self.innerView.center = touchLocation;
lastValidCenter = self.innerView.center;
}else{
NSLog(@"outside");
self.innerView.center = lastValidCenter;
}