2

更新された解決策:主な問題は、速度計算が整数を返す0ことでし1float。結果?ボタンは、起点から終点まで「無限」アニメーション (速度 0 のアニメーション) になっていました。

//////////////////////////////////////

奇妙な:プログラムでビューにいくつかのボタンを描画しています。コードのトラブルシューティング中に、ボタンのフレーム/位置/中心 (場所 A) が実際に表示される場所 (場所 B) と異なることがわかりました。こういう現象は初めて見ました..

(さらに悪いことにhitTest:withEvent:、ボタン自体は場所 B に表示されているにもかかわらず、フレームに基づいてボタンを使用および返すため、実際には場所 A へのタッチでヒット (およびアクションの実行) を追跡しています。)

注意事項と警告:ボタンの 1 つが正しく表示されます。どうしてか分かりません。アニメーションはフレームからはみ出すため、すべてのボタンが正しくアニメーション化されます。

私は自分のコードに何かが欠けていると確信していますが、何時間もかけて、フレームが間違っていると報告していることを考えると、もっと目が必要です!

図:

+-----------------------+
|(mainV)                |
|                       |
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(dW)||
|                 +----+|
|+---------------------+|
||(mV)                 ||
|+---------------------+|
+-----------------------+

伝説:

  • (mainV) = メイン ビュー/ビュー コントローラー、すべての親ビュー
  • (mV) = menuView、(mainV) のサブビュー
  • (dW) = drawButton、(mV) のサブビュー、および他のボタンを作成するための「アンカー」
  • (sB) = sizeButton のインスタンス、(mV) のサブビューhitTest:withEvent:、スーパービューのフレーム外のタッチを取得するために使用

コードとコメント:

最初にボタンを呼び出して作成する中央ボタン作成メソッド。ほとんどの変数はインスタンス変数です

- (void)addSizeSubButtons {

    BOOL showAnimation = NO;

    if ([drawSizeButtonsArray count] == 0) {

        for (int i = 0; i < kNumberOfDrawSizes; i++) {

            // this method is defined below
            // short story is it makes 4 buttons and adds them to an array
            [self makeSizeButton];
        }

        showAnimation = YES;
    }

    // drawSizeButtonsArray is the array from before - see makeSizeButtons below
    for (UIButton *sizeButton in drawSizeButtonsArray) {

        int buttonIndex = [drawSizeButtonsArray indexOfObject:sizeButton];

        // drawButton is my unofficial anchor point - its center is {287.8, -24.25}
        // sizing code in general works and I don't believe is at play here
        // see (dW) in the diagram above..
        [sizeButton setFrame:CGRectMake(0,
                                        0,
                                        drawButton.bounds.size.height * kStackButtonRatio,
                                        drawButton.bounds.size.height * kStackButtonRatio)];

        CGPoint position = CGPointMake(drawButton.center.x,
                                       drawButton.center.y - sizeButton.bounds.size.height * (1.1 + buttonIndex));

        [sizeButton.layer setPosition:position];

        NSLog(@"sizeButton made at %@ named %@",NSStringFromCGPoint(sizeButton.center),sizeButton);

        // NSLog Output (all coords relative to (mV) from legend above:
        // sizeButton made at {287.8, -66.6} (this is loop #1/sizeButton atIndex:0)
        // sizeButton made at {287.8, -105.1} (this is loop #2/sizeButton atIndex:1)
        // sizeButton made at {287.8, -143.6} (this is loop #3/sizeButton atIndex:2)
        // sizeButton made at {287.8, -182.1} (this is loop #4/sizeButton atIndex:3)
        // note: I have tested that the buttons are all different/at different memory addresses
        // --------------------
        // HOWEVER, visual display locations are as follows:
        // button atIndex:0 @ {287.8, -24.25} (remember this is the same as drawButton!)
        // button atIndex:1 @ {287.8, -24.25} (also wrong, and also hidden behind drawButton)
        // button atIndex:2 @ {287.8, -24.25} (three in a row in the wrong place)
        // button atIndex:3 @ {287.8, -182.1} (!! HARK! this one is actually in the right place.. no clue why one is and the other three are not)

        [sizeButton.layer setCornerRadius:sizeButton.bounds.size.width / 7.5];
    }

    // animations are actually working as desired, because they run off the frame
    // as soon as the animation kicks off, buttons all appear in the right place
    // and take the correct action; still, i will include the core method just in case
    if (showAnimation == YES) {

        for (UIButton *sizeButton in drawSizeButtonsArray) {

            // so my button is moving FROM its anchor TO its actual center
            CGPoint origin = drawButton.center;
            CGPoint destination = sizeButton.center;

            // this is just to create a visual effect
            float speed = ( [drawSizeButtonsArray indexOfObject:sizeButton] + 1 ) / [drawSizeButtonsArray count];

            // my central animation method, included below
            CABasicAnimation *slideButton = [self slideButton:sizeButton
                                                    fromPoint:origin
                                                      toPoint:destination
                                                      atSpeed:speed];

            [sizeButton.layer addAnimation:slideButton
                                    forKey:@"slideSizeButtonAnimation"];
        }

    }
}

上から呼び出される Button Creator Helper/Worker メソッド

- (void)makeSizeButton {

    UIButton *sizeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [drawSizeButtonsArray addObject:sizeButton];

    // button presses
    [sizeButton setUserInteractionEnabled:YES];
    [sizeButton addTarget:self
                   action:@selector(drawSizeButtonPressed:)
         forControlEvents:UIControlEventTouchUpInside];

    // TO DO: remove these debug titles and replace with dots
    [sizeButton setTitle:[NSString stringWithFormat:@"%d",[drawSizeButtonsArray indexOfObject:sizeButton]]
                forState:UIControlStateNormal];
    [sizeButton setTitleColor:[UIColor blackColor]
                     forState:UIControlStateNormal];

    [sizeButton setBackgroundColor:[UIColor whiteColor]];

    // show it!
    [self addSubview:sizeButton];
    [self sendSubviewToBack:sizeButton];

}

アニメーション ヘルパー メソッド

- (CABasicAnimation *)slideButton:(UIButton *)button
                        fromPoint:(CGPoint)origin
                          toPoint:(CGPoint)destination
                          atSpeed:(float)speed{

    // now show animation
    CABasicAnimation *slideAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    [slideAnimation setDelegate:self];

    // from & to values
    [slideAnimation setFromValue:[NSValue valueWithCGPoint:origin]];
    [slideAnimation setToValue:[NSValue valueWithCGPoint:destination]];

    // easing in and out.. oh yeah!
    [slideAnimation setDuration:kAnimationTiming / speed];
    CAMediaTimingFunction *easeInOut = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [slideAnimation setTimingFunction:easeInOut];

    NSLog(@"slide animation from %@ to %@",NSStringFromCGPoint(origin),NSStringFromCGPoint(destination));

    // NSLog Output: (all these values are correct/what I intended)
    // AND recall that all animations display properly!
    // in fact, judging by NSLog, everything is working fine.. but visually it is not
    // slide animation from {287.8, -24.25} to {287.8, -66.6} (for button atIndex:0)
    // slide animation from {287.8, -24.25} to {287.8, -105.1} (for button atIndex:1)
    // slide animation from {287.8, -24.25} to {287.8, -143.6} (for button atIndex:2)
    // slide animation from {287.8, -24.25} to {287.8, -182.1} (for button atIndex:3)

    return slideAnimation;
}
4

1 に答える 1

1

アニメーションを無効にしても、この問題は引き続き発生しますか?

ビューのいずれかに変換を適用していますか?

私が注意したいことの1つは、UIViewのフレームを設定してからレイヤーの位置を調整するのは奇妙です。[sizeButton setCenter:position]レイヤーにアクセスするのではなく、使用するのはどうですか。それは問題ではないと思いますが、何か関係があるかもしれません。同様に、CABasicAnimation の世界に飛び込むのではなく、UIView のアニメーション メソッドを使用してみませんか?

于 2012-08-05T16:34:59.063 に答える