0

UIPanGestureRecognizer を適用して 1 本の指で回転し、1 本の指でそのフレームを増減する UIView を 1 つ作成しました。

  • UIView の左下隅に配置されたビューを回転させます。
  • UIView の右下隅に配置されたビューのサイズを変更します。

そのコード行をいくつか書き留めておきます。

//Rotate Apply with Pan Gesture 
    panRotateGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(rotateViewPanGesture:)];
    [rotateView addGestureRecognizer:panRotateGesture];

    //Resize View Apply with Pan Gesture 
    panResizeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(resizeTranslate:)];
    [resizeView addGestureRecognizer:panResizeGesture];

    [panRotateGesture requireGestureRecognizerToFail:panResizeGesture]; 

指一本でUIPanGestureを使ってビューのサイズを変更する方法は次のとおりです。

-(void)resizeTranslate:(UIPanGestureRecognizer *)recognizer
{
    if ([recognizer state]== UIGestureRecognizerStateBegan) 
    {
        prevPoint = [recognizer locationInView:self.superview];
        [self setNeedsDisplay];
    }
    else if ([recognizer state] == UIGestureRecognizerStateChanged)
    {
        if (self.frame.size.width < kFixW)
        {
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, kFixW, self.frame.size.height);
        }

        if(self.frame.size.height < kFixH)
        {
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, kFixH);
        }

        CGPoint point = [recognizer locationInView:self.superview];
        float wChange = 0.0, hChange = 0.0;

        wChange = (point.x - prevPoint.x); //Slow down increment
        hChange = (point.y - prevPoint.y); //Slow down increment 


        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width + (wChange), self.frame.size.height + (hChange));
        NSLog(@"self.frame : %@",NSStringFromCGRect(self.frame));

        prevPoint = [recognizer locationInView:self.superview];

        [self setNeedsDisplay];
    }
    else if ([recognizer state] == UIGestureRecognizerStateEnded)
    {

        prevPoint = [recognizer locationInView:self.superview];
        [self setNeedsDisplay];
    }
}

そして、ここではUIPanGestureでUIViewを1本の指で回転させる場合

-(void)rotateViewPanGesture:(UIPanGestureRecognizer *)recognizer
{
    if ([recognizer state] == UIGestureRecognizerStateBegan) 
    {
        deltaAngle = atan2([recognizer locationInView:self].y-self.center.y, [recognizer locationInView:self].x-self.center.x);
        startTransform = self.transform;
    }
    else if ([recognizer state] == UIGestureRecognizerStateChanged) 
    {
        float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
        float angleDiff = deltaAngle - ang;
        self.transform = CGAffineTransformMakeRotation(-angleDiff);
        [self setNeedsDisplay];
    }
    else if ([recognizer state] == UIGestureRecognizerStateEnded)
    {
        float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
        deltaAngle = atan2([recognizer locationInView:self].y-self.center.y, [recognizer locationInView:self].x-self.center.x);
        startTransform = self.transform;
        [self setNeedsDisplay];
    }
}

問題は、サイズ変更と回転ジェスチャーの両方が正常に機能することです。

panResizeGesture を使用してビューのサイズを変更すると正常に動作しますが、一度 panRotateGesture を適用してから panResizeGesture を適用すると、画面から外れて正しく動作しません。

この問題を解決するための考えを教えてください。

どうもありがとう。

4

2 に答える 2

2

ドキュメントには明確に次のように記載されています。

**変換プロパティが恒等変換でない場合、このプロパティの値は定義されていないため、無視する必要があります。

変換プロパティに非恒等変換が含まれている場合、フレーム プロパティの値は未定義であり、変更しないでください。その場合、center プロパティを使用してビューの位置を変更し、代わりに bounds プロパティを使用してサイズを調整できます。**

したがって、rotateViewPanGesture メソッドで self.frame を self.bounds に変更するだけです

例えば

        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, kFixH);

に:

        self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, kFixH);

あなたのコードは完全に正常に動作します。

アップデート

あなたのコードを使用したサンプルプロジェクトを添付しました。このコードを使用でき ます

于 2012-12-19T10:34:15.920 に答える
0

これは少し遅れていることはわかっているので、すでに理解しているかもしれませんが、コードの locationInView: の部分に問題があります。スーパービューの locationInView を本当に計算したいときに、回転しようとしている実際のビューの locationInView を計算しようとしています。

-(void)rotateViewPanGesture:(UIPanGestureRecognizer *)recognizer{
if ([recognizer state] == UIGestureRecognizerStateBegan) 
{
    deltaAngle = atan2([recognizer locationInView:self.superview].y-self.center.y, [recognizer locationInView:self.superview].x-self.center.x); //here change it to self.superview
    startTransform = self.transform;
}
else if ([recognizer state] == UIGestureRecognizerStateChanged) 
{
    float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
    float angleDiff = deltaAngle - ang;
    self.transform = CGAffineTransformMakeRotation(-angleDiff);
    [self setNeedsDisplay];
}
else if ([recognizer state] == UIGestureRecognizerStateEnded)
{
    float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
    deltaAngle = atan2([recognizer locationInView:self.superview].y-self.center.y, [recognizer locationInView:self.superview].x-self.center.x); //here change it to locationInView:self.superview
    startTransform = self.transform;
    [self setNeedsDisplay];
}}
于 2012-11-20T15:14:36.987 に答える