簡體   English   中英

UIView animateWithDuration 不為cornerRadius 變化設置動畫

[英]UIView animateWithDuration doesn't animate cornerRadius variation

我正在嘗試為UIView實例layercornerRadius的變化設置動畫,但cornerRadius的變化會立即發生。

這是代碼:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
view.layer.masksToBounds = YES;
view.layer.cornerRadius = 10.0;
[UIView animateWithDuration:1.0 animations:^{
    
    [view.layer.cornerRadius = 0.0;
    
}];

謝謝大家誰給我任何提示。

編輯:

我設法使用Core AnimationCABasicAnimation為這個屬性設置Core Animation

 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.fromValue = [NSNumber numberWithFloat:10.0f]; animation.toValue = [NSNumber numberWithFloat:0.0f]; animation.duration = 1.0; [viewToAnimate.layer addAnimation:animation forKey:@"cornerRadius"]; [animation.layer setCornerRadius:0.0];

tl;dr:角半徑在animateWithDuration:animations:animateWithDuration:animations:


文檔中關於視圖動畫的說明。

正如“iOS 視圖編程指南”中關於動畫部分所說

UIKit 和 Core Animation 都提供對動畫的支持,但每種技術提供的支持程度各不相同。 在 UIKit 中,動畫是使用 UIView 對象執行的

您可以使用舊版本制作動畫的完整屬性列表

[UIView beginAnimations:context:];
[UIView setAnimationDuration:];
// Change properties here...
[UIView commitAnimations];

或者更新的

[UIView animateWithDuration:animations:];

(您正在使用的)是:

  • 框架
  • 界限
  • 中央
  • 變換(CGAffineTransform,而不是 CATransform3D)
  • α
  • 背景顏色
  • 內容拉伸

如您所見, cornerRadius不在列表中。

有些困惑

UIView 動畫實際上僅用於動畫視圖屬性。 讓人困惑的是,你還可以在UIView動畫塊內部的圖層上對相同的屬性進行動畫處理,即frame、bounds、position、opacity、backgroundColor。 所以人們在animateWithDuration看到層動畫,並相信他們可以在那里為任何視圖屬性設置動畫。

同一部分繼續說:

在你想要執行更復雜的動畫,或者 UIView 類不支持的動畫的地方,你可以使用 Core Animation 和視圖的底層來創建動畫。 由於視圖和圖層對象錯綜復雜地鏈接在一起,因此對視圖圖層的更改會影響視圖本身。

向下幾行,您可以閱讀 Core Animation 可動畫屬性列表,您可以在其中看到以下內容:

  • 圖層的邊框(包括圖層的角是否圓角)

因此,要為cornerRadius設置動畫,您需要使用 Core Animation,正如您在更新的問題(和答案)中已經說過的那樣。 我只是添加了試圖解釋為什么會這樣。


一些額外的說明

當人們閱讀說animateWithDuration是推薦的動畫方式的文檔時,很容易相信它正在嘗試替換 CABasicAnimation、CAAnimationGroup、CAKeyframeAnimation 等,但實際上並非如此。 它取代了你在上面看到的beginAnimations:context:commitAnimations

我使用這個擴展來動畫改變角半徑:

extension UIView
{
    func animateCornerRadius(from: CGFloat, to: CGFloat, duration: CFTimeInterval)
    {
        CATransaction.begin()
        let animation = CABasicAnimation(keyPath: "cornerRadius")
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        animation.fromValue = from
        animation.toValue = to
        animation.duration = duration
        CATransaction.setCompletionBlock { [weak self] in
            self?.layer.cornerRadius = to
        }
        layer.add(animation, forKey: "cornerRadius")
        CATransaction.commit()
    }
}

可以對角半徑變化進行動畫處理,但唯一的方法是使用 CABasicAnimation。 希望這可以幫助那里的人。

你可以在這里實現 UIView 動畫: http : //maniacdev.com/2013/02/ios-uiview-category-allowing-you-to-set-up-customizable-animation-properties

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
animation.duration = DURATION;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.toValue = @(NEW_CORNER_RADIUS);
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
[view.layer addAnimation:animation forKey:@"setCornerRadius:"];

iOS 10開始,您實際上可以為 cornerRadius 設置動畫:

UIViewPropertyAnimator(duration: 3.0, curve: .easeIn) {
    square.layer.cornerRadius = 20
}.startAnimation()

您可以通過在視圖類中實現-[actionForLayer:forKey]來在+[UIView animateWithDuration:]中使該屬性可動畫化。 有關如何操作的示例,請參閱此問題

CornerRadius 屬性是可動畫的

工作代碼如下

//層初始化

let imageLayer = CALayer() 
imageLayer.frame = CGRect(x: 0, y: 0.0, width: tenPercent, height: tenPercent)
imageLayer.contents = imageNew.cgImage
imageLayer.masksToBounds = true

//動畫初始化

let animationCornerRadius = CABasicAnimation(keyPath: "cornerRadius")
animationCornerRadius.beginTime =  0.01
animationCornerRadius.duration = CFTimeInterval(5)
animationCornerRadius.fromValue = 1
animationCornerRadius.toValue = tenPercent / 2
animationCornerRadius.fillMode = .forwards
animationCornerRadius.isRemovedOnCompletion = false
imageLayer.add(animationCornerRadius , forKey: "cornerRadius")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM