如何制作流畅的 UIView 分割动画?

Posted

技术标签:

【中文标题】如何制作流畅的 UIView 分割动画?【英文标题】:how to make smooth UIView splitting animation? 【发布时间】:2014-03-24 06:35:37 【问题描述】:

您好,我正在尝试使用UIPinchGestureRecognizer 实现拆分UIView,但是如果有人知道如何解决,请解决以下问题。

    这是我的 pinchGestureHandlerCode:

    - (IBAction)splitView:(UIPinchGestureRecognizer*)recognizer
    
        if(recognizer.state == UIGestureRecognizerStateBegan)
        
            CGPoint selectedFolderPoint = CGPointMake([recognizer locationInView:recognizer.view].x,
                                              recognizer.view.frame.origin.y);
            self.splitPosition = ([recognizer locationOfTouch:0 inView:recognizer.view].x +
                          [recognizer locationOfTouch:1 inView:recognizer.view].x)/2;
    
    
        //STEP 1: Capture the Main View Content into an image
        [self captureImageFromPointAndSetupMaskView:selectedFolderPoint];
    
    else if(recognizer.state == UIGestureRecognizerStateChanged)
    
         CGPoint selectedFolderPoint = CGPointMake(recognizer.scale,
                                              recognizer.view.frame.origin.y);
    
        //STEP 2: Reduce the left image width, and move the right image origin according to the finger move of user.
        [self layoutBottomPartOfMainViewRelativeToPointInMainView:selectedFolderPoint];
    
    
        [UIView beginAnimations:@"split" context:NULL];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        //captures the main background view's image
    
        //STEP 3- Push The Layer-3 which hosts the other part of the Main Content View
        [UIView commitAnimations];
    
    
    else if(recognizer.state == UIGestureRecognizerStateEnded)
    
        // STEP 3: remove the both image view from the view.
        [self layoutFinalFrameOfBottomPartOfMainContentView];
        [UIView commitAnimations];
    
    

第 1 步方法:

-(void)captureImageFromPointAndSetupMaskView:(CGPoint)selectedFolderPoint

    UIGraphicsBeginImageContext(self.superview.frame.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

    CGImageRef leftTempRef = backgroundImage.CGImage;
    CGImageRef leftImageRef = CGImageCreateWithImageInRect(leftTempRef, 

CGRectMake(self.bounds.origin.x, self.bounds.origin.y, selectedFolderPoint.x, self.bounds.size.height));

    UIImage *leftImage = [UIImage imageWithCGImage:leftImageRef];

    leftImageBackgroundView = [[UIImageView alloc] initWithImage:leftImage];
    [self.leftBackgroundView addSubview:leftImageBackgroundView];

    CGImageRef rightTempRef = backgroundImage.CGImage;
    CGImageRef rightImageRef = CGImageCreateWithImageInRect(rightTempRef, 

CGRectMake(selectedFolderPoint.x, self.bounds.origin.y, self.superview.bounds.size.width, self.bounds.size.height));

    UIImage *rightImage = [UIImage imageWithCGImage:rightImageRef];

    rightImageBackgroundView = [[UIImageView alloc] initWithImage:rightImage];
    [self.rightBackgroundView addSubview:rightImageBackgroundView];



    [self.leftBackgroundView setFrame:CGRectMake(self.bounds.origin.x,
                                             self.bounds.origin.y,
                                             selectedFolderPoint.x,
                                             self.frame.size.height)];

    [self.rightBackgroundView setFrame:CGRectMake(selectedFolderPoint.x,
                                              self.bounds.origin.y,
                                              self.superview.bounds.size.width,
                                              self.bounds.size.height)];

第 2 步方法:

-(void)layoutBottomPartOfMainViewRelativeToPointInMainView:(CGPoint)selectedFolderPoint

[self.leftBackgroundView setFrame:CGRectMake(self.leftBackgroundView.bounds.origin.x,
                                             self.leftBackgroundView.bounds.origin.y,
                                             (self.leftBackgroundView.bounds.size.width -
                                                selectedFolderPoint.x),
                                             self.leftBackgroundView.bounds.size.height)];

[self.rightBackgroundView setFrame:CGRectMake(self.rightBackgroundView.frame.origin.x + selectedFolderPoint.x,
                                              self.rightBackgroundView.bounds.origin.y,
                                              self.rightBackgroundView.bounds.size.width - selectedFolderPoint.x,
                                              self.rightBackgroundView.bounds.size.height)];

if(((ABS(self.leftBackgroundView.bounds.origin.x+self.leftBackgroundView.bounds.size.width)-
     self.rightBackgroundView.bounds.origin.x) > 100) &&
   ((ABS(self.leftBackgroundView.bounds.origin.x+self.leftBackgroundView.bounds.size.width)-
     self.rightBackgroundView.bounds.origin.x) < 110))

    [self switchView];
    NSDictionary *message;
    [self.timelineController sendEvent:SWITCH_VIEW withMessage:message];
    [self layoutFinalFrameOfBottomPartOfMainContentView];


[UIView setAnimationsEnabled:NO];
[UIView setAnimationsEnabled:YES];

第 3 步方法:

-(void)layoutFinalFrameOfBottomPartOfMainContentView
 
     [self.leftBackgroundView setFrame:CGRectMake(self.bounds.origin.x,
                                             self.leftBackgroundView.bounds.origin.y,
                                             self.bounds.origin.x,
                                               self.leftBackgroundView.bounds.size.height)];

     [self.rightBackgroundView setFrame:CGRectMake(self.bounds.origin.x,
                                              self.rightBackgroundView.bounds.origin.y,
                                              self.bounds.origin.x,
                                              self.rightBackgroundView.bounds.size.height)];

    leftImageBackgroundView.image = nil;
    rightImageBackgroundView.image = nil;

问题是:

    我正在尝试制作流畅的动画,但它运行得太快并且突然向两侧移动。 如果我使用相同的捏合手势,应用程序崩溃并显示内存警告的次数更多。

如果有人知道我在代码中犯了什么错误,请帮助我解决问题,或者有任何其他方法可以做同样的动画,请给我让路....

提前谢谢... ...

【问题讨论】:

【参考方案1】:

像这样定义UIPinchGestureRecognizer

UIPinchGestureRecognizer *ges = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(split)];
[self addGestureRecognizer:ges];

还有这样的拆分方法

- (void)split 
    CGRect f = self.frame;
    CGRect f1 = CGRectMake(CGRectGetMinX(f), f.origin.y, f.size.width/2, f.size.height);
    CGRect f2 = CGRectMake(CGRectGetMidX(f), f.origin.y, f.size.width/2, f.size.height);

    SplitView *view1 = [[[SplitView alloc] initWithFrame:f1] autorelease];
    [self.superview addSubview:view1];

    SplitView *view2 = [[[SplitView alloc] initWithFrame:f2] autorelease];
    [self.superview addSubview:view2];

    f1.origin.x -= 30;
    f2.origin.x += 30;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5];
    view1.frame = f1;
    view2.frame = f2;
    [UIView commitAnimations];

    [self removeFromSuperview];

【讨论】:

不是每次捏合手势触发时(用户移动手指时)都添加两个新的子视图吗? 你能看到我的代码#RajPatil,David Ronnqvist,我想捕捉图像然后分成两部分,然后在移动手指的同时做分割动画(电梯门打开)... .

以上是关于如何制作流畅的 UIView 分割动画?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中获得最流畅的动画?

如何制作流畅的滚动动画?

第一次键盘出现时的动画有时不流畅

我的 UIView 动画很生涩 - 如何优化以下代码?

如何使 SVG 动画无缝流畅?

有没有办法让这个 jquery 悬停动画更流畅?