iOS 13 strange UIView.animation behavior

Viewed 1854

I have cool universal animation which is work fine on iOS 11 and 12.

Before iOS 13

extension UIImage {

    enum ScalingMode {
        case aspectFill
        case aspectFit

        func aspectRatio(between size: CGSize, and otherSize: CGSize) -> CGFloat {
            let aspectWidth  = size.width/otherSize.width
            let aspectHeight = size.height/otherSize.height

            switch self {
            case .aspectFill:
                return max(aspectWidth, aspectHeight)
            case .aspectFit:
                return min(aspectWidth, aspectHeight)
            }
        }
    }

    func scaled(to newSize: CGSize, scalingMode: UIImage.ScalingMode = .aspectFill) -> UIImage {

        let aspectRatio = scalingMode.aspectRatio(between: newSize, and: size)

        var scaledImageRect = CGRect.zero

        scaledImageRect.size.width  = size.width * aspectRatio
        scaledImageRect.size.height = size.height * aspectRatio
        scaledImageRect.origin.x    = (newSize.width - size.width * aspectRatio) / 2.0
        scaledImageRect.origin.y    = (newSize.height - size.height * aspectRatio) / 2.0

        UIGraphicsBeginImageContextWithOptions(newSize, false, 0)

        draw(in: scaledImageRect)
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        return scaledImage!
    }

    func overlayImage(color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, 0)
        let context = UIGraphicsGetCurrentContext()

        color.setFill()

        context!.translateBy(x: 0, y: self.size.height)
        context!.scaleBy(x: 1.0, y: -1.0)

        context!.setBlendMode(CGBlendMode.colorBurn)
        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context!.draw(self.cgImage!, in: rect)

        context!.setBlendMode(CGBlendMode.sourceIn)
        context!.addRect(rect)
        context!.drawPath(using: CGPathDrawingMode.fill)

        let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return coloredImage!
    }
}

open class CustomActivityIndicator: NSObject {

    private var downLogo : UILabel? = nil
    private var topLogo : UILabel? = nil

    private let window = UIApplication.shared.keyWindow!

    open func start() {

        let image = UIImage(named: "1.png")

        let scaledimage = image!.scaled(to: CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height), scalingMode: .aspectFit)

        downLogo = UILabel(frame: UIScreen.main.bounds)
        downLogo!.backgroundColor = UIColor(patternImage: scaledimage.overlayImage(color: UIColor.lightGray))

        topLogo = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: UIScreen.main.bounds.height))
        topLogo!.lineBreakMode = NSLineBreakMode.byClipping
        topLogo!.backgroundColor = UIColor(patternImage: scaledimage)

        window.addSubview(downLogo!)

        window.addSubview(topLogo!)

        UIView.animate(withDuration: 1.5, delay: 0, options: [.curveLinear, .repeat, .autoreverse], animations: { [unowned self] () -> Void in
            self.topLogo!.frame = self.downLogo!.frame

        }, completion: nil)
    }
}

But on iOS 13 we have this behavior.

iOS 13 behavior

As you can see colorful image change coordinates but Xcode shows same coordinates for both images.

I did some testing and found if animate both images it works perfect.

UIView.animate(withDuration: 1.5, delay: 0, options: [.curveLinear, .repeat, .autoreverse], animations: { [unowned self] () -> Void in
        self.topLogo!.frame = self.downLogo!.frame
        self.downLogo!.frame.size.width = UIScreen.main.bounds.width - 1
    }, completion: nil)
1 Answers

Looks like Apple changed something in UILabel class. So changed my label to imageView and now it is working perfect.

Related