复制图层并移动它

问题描述 投票:2回答:2

我想创建一个动画,“创建视图的副本,将此副本从一个点移动到另一个点,同时降低不透明度,直到它完全消失”。

我想我需要通过CABasicAnimation这样做,所以我尝试了类似的东西:

    CGPoint point = CGPointMake(200, 0);

    // copy layer
    CALayer *layer = [[CALayer alloc] initWithLayer:self.animatedView.layer];
    [self.animatedView.layer addSublayer:layer];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.fromValue = [layer valueForKey:@"position"];
    animation.toValue = [NSValue valueWithCGPoint:point];
    animation.duration = 2.0f;

    CABasicAnimation *oanimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    oanimation.fromValue = @1;
    oanimation.toValue = @0;
    oanimation.duration = 1.0f;

    // move copy layer
    [layer addAnimation:animation forKey:@"position"];
    [layer addAnimation:oanimation forKey:@"opacity"];

但是没有附加,我认为这是关于文档的正常情况:

此初始化程序用于创建图层的阴影副本,例如,用于presentationLayer方法。在任何其他情况下使用此方法将产生未定义的行为。例如,不要使用此方法初始化具有现有图层内容的新图层。

有人之前已经做过这种动画吗?

谢谢你的帮助。

ios calayer caanimation
2个回答
1
投票
UIGraphicsBeginImageContext(theView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[theView.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageView *imgView = [[UIImageView alloc] initWithImage:screenShot];
imgView.frame = theView.frame;
[self.view addSubview:imgView];

然后玩'imgView':)


0
投票

Solution 1: CALayers

我在Swift 4.2中改编了@Sriram解决方案,并且更喜欢使用更适合的CALayer而不是UIImageView

// We use the screen's scale to support Retina displays
UIGraphicsBeginImageContextWithOptions(viewToCopy.frame.size, false, UIScreen.main.scale)
if let context: CGContext = UIGraphicsGetCurrentContext() {
    // We convert the layer of the viewToCopy into an UIImage
    viewToCopy.layer.render(in: context)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    // We create a layer that will hold the image. This layer can be animated further down the road.
    let layer = CALayer()
    layer.contents = screenshot?.cgImage // Don't forget .cgImage, otherwise it won't work
    layer.frame = viewToCopy.frame // For example
    view.layer.addSublayer(layer)
}

我想这个适用于大多数情况都适用,但我在使用UIVisualEffectView(效果破坏)时遇到了一些问题。所以我不得不想出第二个解决方案。

Solution 2: UIView Copy

首先,您需要对UIView进行一次小扩展才能轻松复制它。我使用了this answer,但为了清楚起见,我会在这里复制它。

// MARK: - UIView + Copy

extension UIView {
    func copyView<T: UIView>() -> T {
        return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
    }
}

完成后,您可以复制视图,添加视图并将其放置在视图层次结构中,并像使用任何其他UIView一样使用它。

let animationCardView = cardView.copyView()
animationCardView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(animationCardView)

NSLayoutConstraint.activate([animationCardView.leadingAnchor.constraint(equalTo: cardView.leadingAnchor),
                                     animationCardView.trailingAnchor.constraint(equalTo: cardView.trailingAnchor),
                                     animationCardView.topAnchor.constraint(equalTo: cardView.topAnchor),
                                     animationCardView.bottomAnchor.constraint(equalTo: cardView.bottomAnchor)])
© www.soinside.com 2019 - 2024. All rights reserved.