当我放大屏幕时,我的uipangesturerecognizer有问题 .
我的应用程序有一个带uiview的uiviewcontroller .
在这个视图中,我有一个几乎占整个屏幕边界一半的calayer .
这个calayer有几个子层,用户可以拖动(uipangesture),添加(uitapgesture)和删除(doubletapgesture) . 为了更准确地拖动,我在uiview中添加了一个uipinchgesture方法来放大和缩小 .
此时一切正常,除非我放大并尝试移动(pangesture)子层 . 有时工作,但通常不工作(没有放大总是工作正常) .
我不知道我的代码是否有问题,或者可能不是这样做的 . 有什么我想念的吗?
我在sdk 4.2下 .
这些是我的代码:
- (id)initWithFrame:(CGRect)frame
{
[super initWithFrame:frame];
(…)
perfil = [[CALayer alloc] init]; //the calayer of the uiview
[perfil setBounds:CGRectMake(0, 0, wide, heigth/2)];
[[self layer] addSublayer:perfil];
//I add the sublayers to the "peril" layer when the user touch an "edit button" and that works fine
//UIGsture Recognizers
UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapFrom:)];
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapFrom:)];
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchFrom:)];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[panGestureRecognizer setMinimumNumberOfTouches:1];
[panGestureRecognizer setMaximumNumberOfTouches:1];
[singleTapRecognizer setNumberOfTapsRequired:1];
[singleTapRecognizer setCancelsTouchesInView:NO];
[doubleTapRecognizer setNumberOfTapsRequired:2];
[self addGestureRecognizer:singleTapRecognizer];
[self addGestureRecognizer:doubleTapRecognizer];
[self addGestureRecognizer:pinchGestureRecognizer];
[self addGestureRecognizer:panGestureRecognizer];
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
singleTapRecognizer.delegate = self;
doubleTapRecognizer.delegate = self;
pinchGestureRecognizer.delegate = self;
panGestureRecognizer.delegate = self;
//Some other different stuff here
}
- (void) handlePanFrom: (id)sender
{
CGPoint point = [(UIPanGestureRecognizer*)sender locationInView:self];
boxLayer = [[self perfil] hitTest:point];
[self becomeFirstResponder];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan)
{
numberOfSublayer = 1000; //declared as a int in UIView.h
for (CALayer *elements in [perfil sublayers])
{
if([boxLayer isEqual:elements])
{
numberOfSublayer = [[perfil sublayers] indexOfObject:elements];
break;
}
}
}
(…) //Some more operations once I found the sublayer
}
- (void) handlePinchFrom: (id)sender
{
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded)
{
lastScale = 1.0;
return;
}
if ([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan ||
[(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[sender view].layer valueForKeyPath:@"transform.scale"] floatValue];
const CGFloat kMaxScale = 4.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[sender view] transform], newScale, newScale);
[sender view].transform = transform;
if ([perfil sublayers])
{
for (CALayer *elements in [perfil sublayers]) //Here I try to adjust the zoom to the sublayers
{
//Here is one first approach
//CGAffineTransform transformELS = CGAffineTransformScale([elements affineTransform], 7/(newScale+6), 7/(newScale+6));
//[elements setAffineTransform:transformELS];
//Here is a second approach
[elements setBounds:CGRectMake(0, 0, elements.bounds.size.width*7/(newScale+6), elements.bounds.size.height*7/(newScale+6))];
}
}
lastScale = [(UIPinchGestureRecognizer*)sender scale];
(…) //Some other different stuff here
}
非常感谢你 .
2 回答
如果没有看到sublayer hittest代码真的很难说,但是当您重新缩放父视图/图层时,重新缩放子图层似乎很奇怪 .
您只需要缩放父图层,所有子项将依次缩放 .
所有这些手动生成的夹紧和平移代码都充满了危险 . 它可以做到,但我发现你最终得意大利面 .
将视图放在UIScrollView中,让它完成
perfil
视图的捏合和平移工作 .这是UIScrollView平移和缩放的十亿个例子 . 谷歌和SO会知道你是否还没有 .
我希望在父视图的touchBegan事件中捕获子层的平移 .
这是我用来捕获子层中的命中
而这在父视图的touchesBegan / touchesMoved中 . (保留对scrollview的弱引用)
该代码既不完整也不检查bug,但应该让你接近 .
最后,我的解决方案对我来说非常有用UIPanGestureRecognizer starting point is off . 谢谢 .