3

次の問題があります。UIView の半分を残りの半分に折りたたむことができるメソッドを書きたいと思います。

アルゴリズムは私には明らかです (少なくとも私はそう思いますが、何かを忘れている可能性があります)。

  1. UIView のレンダリング イメージを作成する
  2. 折りたい半分に応じて分割します
  3. レンダリングされたイメージの対応する半分を対応するレイヤーに追加します
  4. 2 つのレイヤーを、背景が白でコンテンツがない backgroundlayer に追加します (ビューの元のレイヤーを覆うために白い背景を作成するためだけに存在します)。
  5. ビュー レイヤーに backgroundlayer を追加します。
  6. 折りたたみレイヤーの変換を設定します
  7. アニメーションを開始する

動作するはずですが、動作しません! そして、私には理由がわかりません。:(

メソッドのソースコードは次のとおりです。

-(void)foldView:(UIView *) view withDuration: (NSTimeInterval) duration toSide: (NSString*) side withReverse: (bool) reverse andRepeatCount:(float) repeatCount
{
    //create Screenshot from view to fold
    UIGraphicsBeginImageContext(view.bounds.size);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *img_view = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //Bildausschnitte festlegen
    CGRect rect_closingImageHalf = view.bounds;    
    CGRect rect_fixedImageHalf = view.bounds;    

    CGPoint pt_anchorOpeningImageHalf;
    CGPoint pt_anchorFixedImageHalf;

    CATransform3D transform;

    CALayer *lay_closingImageHalf;
    CALayer *lay_fixedImageHalf;
    lay_fixedImageHalf.masksToBounds = YES;
    lay_closingImageHalf.masksToBounds = YES;
    //get white backside of layer which folds
    lay_closingImageHalf.doubleSided = NO;


    //white backgroundlayer to hide the layer of the image
    CALayer *backgroundAnimationLayer = [CALayer layer];
    backgroundAnimationLayer.frame = view.frame;
    backgroundAnimationLayer.backgroundColor = [[UIColor whiteColor] CGColor];

    //determine direction in which to fold    
    if ([side isEqualToString:k_side_vonLinks]) 
    {
        rect_closingImageHalf = CGRectMake(0, 0, img_view.size.width / 2, img_view.size.height);
        rect_fixedImageHalf = CGRectMake(img_view.size.width / 2, 0, img_view.size.width / 2, img_view.size.height);

        pt_anchorOpeningImageHalf = CGPointMake(1.0, 0.5);        
        pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);

        transform = CATransform3DMakeRotation(M_PI, 0, 1.0, 0);
    }
    else if([side isEqualToString:k_side_vonRechts])
    {
        rect_closingImageHalf = CGRectMake(img_view.size.width / 2, 0, img_view.size.width / 2, img_view.size.height);
        rect_fixedImageHalf = CGRectMake(0, 0, img_view.size.width / 2, img_view.size.height);

        pt_anchorOpeningImageHalf = CGPointMake(0.0, 0.5);
        pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);   

        transform = CATransform3DMakeRotation(M_PI, 0, 1.0, 0);
    }
    else if([side isEqualToString:k_side_vonOben])
    {
        rect_closingImageHalf = CGRectMake(0, 0, img_view.size.width, img_view.size.height / 2);
        rect_fixedImageHalf = CGRectMake(0, img_view.size.height / 2, img_view.size.width, img_view.size.height / 2);

        pt_anchorOpeningImageHalf = CGPointMake(0.5, 1.0);
        pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);

        transform = CATransform3DMakeRotation(M_PI, 1.0, 0, 0);
    }
    else if([side isEqualToString:k_side_vonUnten])
    {
        rect_closingImageHalf = CGRectMake(0, img_view.size.height / 2, img_view.size.width, img_view.size.height / 2);
        rect_fixedImageHalf = CGRectMake(0, 0, img_view.size.width, img_view.size.height / 2);

        pt_anchorOpeningImageHalf = CGPointMake(0.5, 0.0);
        pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);

        transform = CATransform3DMakeRotation(M_PI, 1.0, 0, 0);
    }

    CGImageRef img_closingHalf = CGImageCreateWithImageInRect( [img_view CGImage], rect_closingImageHalf);
    CGImageRef img_fixedHalf = CGImageCreateWithImageInRect( [img_view CGImage], rect_fixedImageHalf);    

    lay_closingImageHalf.anchorPoint = pt_anchorOpeningImageHalf;
    lay_fixedImageHalf.anchorPoint = pt_anchorFixedImageHalf;


    //add the rendered image of the view to the backgroundLayer
    [backgroundAnimationLayer addSublayer:lay_fixedImageHalf];
    [backgroundAnimationLayer addSublayer:lay_closingImageHalf];
    lay_closingImageHalf.contents = (__bridge id)img_closingHalf;
    lay_fixedImageHalf.contents = (__bridge id)img_fixedHalf;


    [view.layer addSublayer:backgroundAnimationLayer];

    //add perspective
    transform.m34 = 1.0f / 2500.0f;

    //animate the folding of the layer
    CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    flipAnimation.toValue = [NSValue valueWithCATransform3D:transform];
    flipAnimation.duration = duration;
    flipAnimation.autoreverses = reverse;
    flipAnimation.repeatCount = repeatCount;
    flipAnimation.delegate = self;
    flipAnimation.removedOnCompletion = NO;
    flipAnimation.fillMode = kCAFillModeForwards;

    [backgroundAnimationLayer addAnimation:flipAnimation forKey:@"fold"];
}

あなたの誰かがなぜそれがうまくいかないのか考えているなら、彼が助けてくれればとてもうれしいです. 私はほぼ一日グーグルで検索し、多くのサンプルを読みましたが、間違いを見つけることができません. また、このタスクの非常に優れた例であるAFKPageFLipperも調べましたが、残念ながら、コードの問題点を見つけるのに役立ちませんでした。

誰かが私を助けてくれることを願っています。

4

2 に答える 2

4

作成しようとしている効果を含む次の 2 つのプロジェクトを見てください。

https://github.com/blommegard/SBTickerView

https://github.com/raweng/FlipView

于 2011-12-20T14:53:05.313 に答える
1

そのはず

CALayer *lay_closingImageHalf = [CALayer layer];
CALayer *lay_fixedImageHalf = [CALayer layer];

それ以外の

CALayer *lay_closingImageHalf;
CALayer *lay_fixedImageHalf;

少なくとも。

lay_closingImageHalfまた、とのフレームを設定する必要がありますlay_fixedImageHalf

[lay_closingImageHalf setFrame:rect_closingImageHalf];
[lay_fixedImageHalf setFrame:rect_fixedImageHalf];

それでもフリップアニメーションは折り畳まれません...あなたのコードですか?

于 2011-12-20T14:34:09.957 に答える