mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
UI optimizations
This commit is contained in:
parent
5c71c08b6e
commit
5f3de7a40b
@ -5,7 +5,7 @@ import Lottie
|
||||
import AppBundle
|
||||
import Display
|
||||
|
||||
public final class AnimationNode : ASDisplayNode {
|
||||
public final class AnimationNode: ASDisplayNode {
|
||||
private let scale: CGFloat
|
||||
public var speed: CGFloat = 1.0 {
|
||||
didSet {
|
||||
@ -15,8 +15,6 @@ public final class AnimationNode : ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
//private var colorCallbacks: [LOTColorValueCallback] = []
|
||||
|
||||
public var didPlay = false
|
||||
public var completion: (() -> Void)?
|
||||
private var internalCompletion: (() -> Void)?
|
||||
@ -43,9 +41,6 @@ public final class AnimationNode : ASDisplayNode {
|
||||
if let colors = colors {
|
||||
for (key, value) in colors {
|
||||
view.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
|
||||
/*let colorCallback = LOTColorValueCallback(color: value.cgColor)
|
||||
self.colorCallbacks.append(colorCallback)
|
||||
view.setValueDelegate(colorCallback, for: LOTKeypath(string: "\(key).Color"))*/
|
||||
}
|
||||
|
||||
if let value = colors["__allcolors__"] {
|
||||
@ -77,9 +72,6 @@ public final class AnimationNode : ASDisplayNode {
|
||||
if let colors = colors {
|
||||
for (key, value) in colors {
|
||||
view.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
|
||||
/*let colorCallback = LOTColorValueCallback(color: value.cgColor)
|
||||
self.colorCallbacks.append(colorCallback)
|
||||
view.setValueDelegate(colorCallback, for: LOTKeypath(string: "\(key).Color"))*/
|
||||
}
|
||||
|
||||
if let value = colors["__allcolors__"] {
|
||||
@ -121,9 +113,6 @@ public final class AnimationNode : ASDisplayNode {
|
||||
if let colors = colors {
|
||||
for (key, value) in colors {
|
||||
self.animationView()?.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
|
||||
/*let colorCallback = LOTColorValueCallback(color: value.cgColor)
|
||||
self.colorCallbacks.append(colorCallback)
|
||||
self.animationView()?.setValueDelegate(colorCallback, for: LOTKeypath(string: "\(key).Color"))*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,6 @@ func localizedCountryNamesAndCodes(strings: PresentationStrings) -> [((String, S
|
||||
}
|
||||
}
|
||||
result.append(((englishCountryName, countryName), country.id, codes))
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
@ -6,6 +6,22 @@ public enum DeviceType {
|
||||
}
|
||||
|
||||
public enum DeviceMetrics: CaseIterable, Equatable {
|
||||
public struct Performance {
|
||||
public let isGraphicallyCapable: Bool
|
||||
|
||||
init() {
|
||||
var length: Int = 4
|
||||
var cpuCount: UInt32 = 0
|
||||
sysctlbyname("hw.ncpu", &cpuCount, &length, nil, 0)
|
||||
|
||||
#if DEBUG
|
||||
cpuCount = 2
|
||||
#endif
|
||||
|
||||
self.isGraphicallyCapable = cpuCount >= 6
|
||||
}
|
||||
}
|
||||
|
||||
case iPhone4
|
||||
case iPhone5
|
||||
case iPhone6
|
||||
@ -33,6 +49,8 @@ public enum DeviceMetrics: CaseIterable, Equatable {
|
||||
case iPadPro3rdGen
|
||||
case iPadMini6thGen
|
||||
case unknown(screenSize: CGSize, statusBarHeight: CGFloat, onScreenNavigationHeight: CGFloat?)
|
||||
|
||||
public static let performance = Performance()
|
||||
|
||||
public static var allCases: [DeviceMetrics] {
|
||||
return [
|
||||
|
@ -290,7 +290,7 @@ private final class ChatListViewSpaceState {
|
||||
|
||||
postboxLog("existingEntityIds not unique: \(allEntityIds)")
|
||||
postboxLog("allIndices: \(allIndices)")
|
||||
assert(false)
|
||||
//assert(false)
|
||||
//preconditionFailure()
|
||||
}
|
||||
|
||||
|
@ -327,8 +327,6 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe
|
||||
let animationNode = AnimationNode(animation: animationName, colors: colors, scale: 1.0)
|
||||
self.animationNode = animationNode
|
||||
|
||||
animationNode.animationView()?.logHierarchyKeypaths()
|
||||
|
||||
let animationBackgroundNode = ASDisplayNode()
|
||||
animationBackgroundNode.cornerRadius = 20.0
|
||||
animationBackgroundNode.backgroundColor = backgroundColor
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import TelegramUIPreferences
|
||||
import Postbox
|
||||
@ -28,6 +29,10 @@ public func selectReactionFillStaticColor(theme: PresentationTheme, wallpaper: T
|
||||
}
|
||||
|
||||
public func dateFillNeedsBlur(theme: PresentationTheme, wallpaper: TelegramWallpaper) -> Bool {
|
||||
if !DeviceMetrics.performance.isGraphicallyCapable {
|
||||
return false
|
||||
}
|
||||
|
||||
if case .builtin = wallpaper {
|
||||
return false
|
||||
} else if case .color = wallpaper {
|
||||
|
@ -353,6 +353,7 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
||||
"//submodules/TelegramUI/Components/StorageUsageScreen",
|
||||
"//submodules/TelegramUI/Components/AvatarEditorScreen",
|
||||
"//submodules/TelegramUI/Components/LottieComponent",
|
||||
"//submodules/MediaPasteboardUI:MediaPasteboardUI",
|
||||
"//submodules/DrawingUI:DrawingUI",
|
||||
"//submodules/FeaturedStickersScreen:FeaturedStickersScreen",
|
||||
|
@ -39,10 +39,10 @@ private final class LottieDirectContent: LottieComponent.Content {
|
||||
return true
|
||||
}
|
||||
|
||||
override func load(_ f: @escaping (Data) -> Void) -> Disposable {
|
||||
override func load(_ f: @escaping (Data, String?) -> Void) -> Disposable {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.path)) {
|
||||
let result = TGGUnzipData(data, 2 * 1024 * 1024) ?? data
|
||||
f(result)
|
||||
f(result, nil)
|
||||
}
|
||||
|
||||
return EmptyDisposable
|
||||
|
@ -15,6 +15,7 @@ swift_library(
|
||||
"//submodules/Components/HierarchyTrackingLayer",
|
||||
"//submodules/rlottie:RLottieBinding",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/AppBundle",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -5,7 +5,7 @@ import ComponentFlow
|
||||
import HierarchyTrackingLayer
|
||||
import RLottieBinding
|
||||
import SwiftSignalKit
|
||||
import Accelerate
|
||||
import AppBundle
|
||||
|
||||
public final class LottieComponent: Component {
|
||||
public typealias EnvironmentType = Empty
|
||||
@ -25,10 +25,36 @@ public final class LottieComponent: Component {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
open func load(_ f: @escaping (Data) -> Void) -> Disposable {
|
||||
open func load(_ f: @escaping (Data, String?) -> Void) -> Disposable {
|
||||
preconditionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
public final class AppBundleContent: Content {
|
||||
public let name: String
|
||||
|
||||
public init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
override public func isEqual(to other: Content) -> Bool {
|
||||
guard let other = other as? AppBundleContent else {
|
||||
return false
|
||||
}
|
||||
if self.name != other.name {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override public func load(_ f: @escaping (Data, String?) -> Void) -> Disposable {
|
||||
if let url = getAppBundle().url(forResource: self.name, withExtension: "json"), let data = try? Data(contentsOf: url) {
|
||||
f(data, url.path)
|
||||
}
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public let content: Content
|
||||
public let color: UIColor
|
||||
@ -63,6 +89,9 @@ public final class LottieComponent: Component {
|
||||
private var currentFrame: Int = 0
|
||||
private var currentFrameStartTime: Double?
|
||||
|
||||
private var hierarchyTrackingLayer: HierarchyTrackingLayer?
|
||||
private var isVisible: Bool = false
|
||||
|
||||
private var displayLink: SharedDisplayLinkDriver.Link?
|
||||
|
||||
private var currentTemplateFrameImage: UIImage?
|
||||
@ -76,11 +105,30 @@ public final class LottieComponent: Component {
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
//self.hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
//self.layer.addSublayer(self.hierarchyTrackingLayer)
|
||||
let hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
self.hierarchyTrackingLayer = hierarchyTrackingLayer
|
||||
self.layer.addSublayer(hierarchyTrackingLayer)
|
||||
|
||||
hierarchyTrackingLayer.didEnterHierarchy = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if !self.isVisible {
|
||||
self.isVisible = true
|
||||
self.visibilityUpdated()
|
||||
}
|
||||
}
|
||||
hierarchyTrackingLayer.didExitHierarchy = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if self.isVisible {
|
||||
self.isVisible = false
|
||||
self.visibilityUpdated()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@ -91,11 +139,22 @@ public final class LottieComponent: Component {
|
||||
self.currentContentDisposable?.dispose()
|
||||
}
|
||||
|
||||
private func visibilityUpdated() {
|
||||
if self.isVisible {
|
||||
if self.scheduledPlayOnce {
|
||||
self.playOnce()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func playOnce(delay: Double = 0.0) {
|
||||
guard let _ = self.animationInstance else {
|
||||
self.scheduledPlayOnce = true
|
||||
return
|
||||
}
|
||||
if !self.isVisible {
|
||||
return
|
||||
}
|
||||
|
||||
self.scheduledPlayOnce = false
|
||||
|
||||
@ -135,8 +194,8 @@ public final class LottieComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
private func loadAnimation(data: Data) {
|
||||
self.animationInstance = LottieInstance(data: data, fitzModifier: .none, colorReplacements: nil, cacheKey: "")
|
||||
private func loadAnimation(data: Data, cacheKey: String?) {
|
||||
self.animationInstance = LottieInstance(data: data, fitzModifier: .none, colorReplacements: nil, cacheKey: cacheKey ?? "")
|
||||
if self.scheduledPlayOnce {
|
||||
self.scheduledPlayOnce = false
|
||||
self.playOnce()
|
||||
@ -184,12 +243,6 @@ public final class LottieComponent: Component {
|
||||
return
|
||||
}
|
||||
|
||||
var destinationBuffer = vImage_Buffer()
|
||||
destinationBuffer.width = UInt(context.scaledSize.width)
|
||||
destinationBuffer.height = UInt(context.scaledSize.height)
|
||||
destinationBuffer.data = context.bytes
|
||||
destinationBuffer.rowBytes = context.bytesPerRow
|
||||
|
||||
animationInstance.renderFrame(with: Int32(self.currentFrame % Int(animationInstance.frameCount)), into: context.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(currentDisplaySize.width), height: Int32(currentDisplaySize.height), bytesPerRow: Int32(context.bytesPerRow))
|
||||
self.currentTemplateFrameImage = context.generateImage()?.withRenderingMode(.alwaysTemplate)
|
||||
self.image = self.currentTemplateFrameImage
|
||||
@ -216,12 +269,12 @@ public final class LottieComponent: Component {
|
||||
if previousComponent?.content != component.content {
|
||||
self.currentContentDisposable?.dispose()
|
||||
let content = component.content
|
||||
self.currentContentDisposable = component.content.load { [weak self, weak content] data in
|
||||
self.currentContentDisposable = component.content.load { [weak self, weak content] data, cacheKey in
|
||||
Queue.mainQueue().async {
|
||||
guard let self, self.component?.content == content else {
|
||||
return
|
||||
}
|
||||
self.loadAnimation(data: data)
|
||||
self.loadAnimation(data: data, cacheKey: cacheKey)
|
||||
}
|
||||
}
|
||||
} else if redrawImage {
|
||||
|
@ -30,7 +30,7 @@ public extension LottieComponent {
|
||||
return true
|
||||
}
|
||||
|
||||
override public func load(_ f: @escaping (Data) -> Void) -> Disposable {
|
||||
override public func load(_ f: @escaping (Data, String?) -> Void) -> Disposable {
|
||||
let fileId = self.fileId
|
||||
let mediaBox = self.context.account.postbox.mediaBox
|
||||
return (self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId])
|
||||
@ -60,7 +60,7 @@ public extension LottieComponent {
|
||||
guard let data else {
|
||||
return
|
||||
}
|
||||
f(data)
|
||||
f(data, nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if (strongSelf.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion {
|
||||
return
|
||||
}
|
||||
strongSelf.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
|
||||
if DeviceMetrics.performance.isGraphicallyCapable {
|
||||
strongSelf.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
|
||||
}
|
||||
}
|
||||
|
||||
getMessageTransitionNode = { [weak self] in
|
||||
@ -2214,7 +2216,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if (self.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion {
|
||||
return
|
||||
}
|
||||
self.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
|
||||
if DeviceMetrics.performance.isGraphicallyCapable {
|
||||
self.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
|
||||
}
|
||||
}
|
||||
//self.historyNode.didScrollWithOffset?(listBottomInset - previousListBottomInset, transition, nil)
|
||||
}
|
||||
|
@ -184,10 +184,16 @@ final class ChatLoadingPlaceholderNode: ASDisplayNode {
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
self.containerNode.addSubnode(self.backgroundColorNode)
|
||||
self.containerNode.addSubnode(self.effectNode)
|
||||
|
||||
if DeviceMetrics.performance.isGraphicallyCapable {
|
||||
self.containerNode.addSubnode(self.effectNode)
|
||||
}
|
||||
|
||||
self.addSubnode(self.borderNode)
|
||||
self.borderNode.addSubnode(self.borderEffectNode)
|
||||
|
||||
if DeviceMetrics.performance.isGraphicallyCapable {
|
||||
self.borderNode.addSubnode(self.borderEffectNode)
|
||||
}
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
@ -196,7 +202,9 @@ final class ChatLoadingPlaceholderNode: ASDisplayNode {
|
||||
self.containerNode.view.mask = self.maskNode.view
|
||||
self.borderNode.view.mask = self.borderMaskNode.view
|
||||
|
||||
self.backgroundNode?.updateIsLooping(true)
|
||||
if DeviceMetrics.performance.isGraphicallyCapable {
|
||||
self.backgroundNode?.updateIsLooping(true)
|
||||
}
|
||||
}
|
||||
|
||||
private var bottomInset: (Int, CGFloat)?
|
||||
|
@ -12,6 +12,7 @@ import AudioBlob
|
||||
import ChatPresentationInterfaceState
|
||||
import ComponentFlow
|
||||
import LottieAnimationComponent
|
||||
import LottieComponent
|
||||
|
||||
private let offsetThreshold: CGFloat = 10.0
|
||||
private let dismissOffsetThreshold: CGFloat = 70.0
|
||||
@ -289,11 +290,17 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var micLock: (UIView & TGModernConversationInputMicButtonLock) = {
|
||||
let lockView = LockView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 40.0, height: 60.0)), theme: self.theme, strings: self.strings)
|
||||
lockView.addTarget(self, action: #selector(handleStopTap), for: .touchUpInside)
|
||||
return lockView
|
||||
}()
|
||||
private var micLockValue: (UIView & TGModernConversationInputMicButtonLock)?
|
||||
private var micLock: UIView & TGModernConversationInputMicButtonLock {
|
||||
if let current = self.micLockValue {
|
||||
return current
|
||||
} else {
|
||||
let lockView = LockView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 40.0, height: 60.0)), theme: self.theme, strings: self.strings)
|
||||
lockView.addTarget(self, action: #selector(handleStopTap), for: .touchUpInside)
|
||||
self.micLockValue = lockView
|
||||
return lockView
|
||||
}
|
||||
}
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, presentController: @escaping (ViewController) -> Void) {
|
||||
self.theme = theme
|
||||
@ -363,37 +370,34 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
animationName = "anim_micToVideo"
|
||||
}
|
||||
|
||||
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
|
||||
if previousMode != mode {
|
||||
animationMode = .animating(loop: false)
|
||||
}
|
||||
//var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
|
||||
|
||||
let colorKeys = ["__allcolors__"]
|
||||
/*let colorKeys = ["__allcolors__"]
|
||||
var colors: [String: UIColor] = [:]
|
||||
for colorKey in colorKeys {
|
||||
colors[colorKey] = self.theme.chat.inputPanel.panelControlColor.blitOver(self.theme.chat.inputPanel.inputBackgroundColor, alpha: 1.0)
|
||||
}
|
||||
}*/
|
||||
|
||||
let _ = animationView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieAnimationComponent(
|
||||
animation: LottieAnimationComponent.AnimationItem(
|
||||
name: animationName,
|
||||
mode: animationMode
|
||||
),
|
||||
colors: colors,
|
||||
size: animationFrame.size
|
||||
component: AnyComponent(LottieComponent(
|
||||
content: LottieComponent.AppBundleContent(name: animationName),
|
||||
color: self.theme.chat.inputPanel.panelControlColor.blitOver(self.theme.chat.inputPanel.inputBackgroundColor, alpha: 1.0)
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: animationFrame.size
|
||||
)
|
||||
|
||||
if let view = animationView.view {
|
||||
if let view = animationView.view as? LottieComponent.View {
|
||||
view.isUserInteractionEnabled = false
|
||||
if view.superview == nil {
|
||||
self.insertSubview(view, at: 0)
|
||||
}
|
||||
view.frame = animationFrame
|
||||
|
||||
if previousMode != mode {
|
||||
view.playOnce()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,7 +408,7 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
|
||||
self.pallete = legacyInputMicPalette(from: theme)
|
||||
self.micDecorationValue?.setColor(self.theme.chat.inputPanel.actionControlFillColor)
|
||||
(self.micLock as? LockView)?.updateTheme(theme)
|
||||
(self.micLockValue as? LockView)?.updateTheme(theme)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
@ -33,6 +33,7 @@ import ChatControllerInteraction
|
||||
import UndoUI
|
||||
import PremiumUI
|
||||
import StickerPeekUI
|
||||
import LottieComponent
|
||||
|
||||
private let accessoryButtonFont = Font.medium(14.0)
|
||||
private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers])
|
||||
@ -184,11 +185,11 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
if let animationView = self.animationView {
|
||||
let width = AccessoryItemIconButtonNode.calculateWidth(item: item, image: image, text: "", strings: self.strings)
|
||||
let iconSize = CGSize(width: width, height: width)
|
||||
//let iconSize = CGSize(width: width, height: width)
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floor((size.width - width) / 2.0), y: floor((size.height - width) / 2.0) - bottomInset), size: CGSize(width: width, height: width))
|
||||
|
||||
let colorKeys: [String] = ["__allcolors__"]
|
||||
//let colorKeys: [String] = ["__allcolors__"]
|
||||
let animationName: String
|
||||
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
|
||||
|
||||
@ -286,30 +287,30 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
}
|
||||
}
|
||||
|
||||
var colors: [String: UIColor] = [:]
|
||||
/*var colors: [String: UIColor] = [:]
|
||||
for colorKey in colorKeys {
|
||||
colors[colorKey] = self.theme.chat.inputPanel.inputControlColor.blitOver(self.theme.chat.inputPanel.inputBackgroundColor, alpha: 1.0)
|
||||
}
|
||||
}*/
|
||||
|
||||
let animationSize = animationView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieAnimationComponent(
|
||||
animation: LottieAnimationComponent.AnimationItem(
|
||||
name: animationName,
|
||||
mode: animationMode
|
||||
),
|
||||
colors: colors,
|
||||
size: iconSize
|
||||
component: AnyComponent(LottieComponent(
|
||||
content: LottieComponent.AppBundleContent(name: animationName),
|
||||
color: self.theme.chat.inputPanel.inputControlColor.blitOver(self.theme.chat.inputPanel.inputBackgroundColor, alpha: 1.0)
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: animationFrame.size
|
||||
)
|
||||
if let view = animationView.view {
|
||||
if let view = animationView.view as? LottieComponent.View {
|
||||
view.isUserInteractionEnabled = false
|
||||
if view.superview == nil {
|
||||
self.view.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: animationFrame.minX + floor((animationFrame.width - animationSize.width) / 2.0), y: animationFrame.minY + floor((animationFrame.height - animationSize.height) / 2.0)), size: animationSize)
|
||||
|
||||
if case .animating = animationMode {
|
||||
view.playOnce()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
_animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast<const char *>(data.bytes), data.length), std::string([cacheKey UTF8String]), "", false, colorsVector, modifier);
|
||||
_animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast<const char *>(data.bytes), data.length), std::string([cacheKey UTF8String]), "", cacheKey.length != 0, colorsVector, modifier);
|
||||
if (_animation == nullptr) {
|
||||
return nil;
|
||||
}
|
||||
|
@ -22,4 +22,8 @@
|
||||
#define LOTTIE_IMAGE_MODULE_DISABLED
|
||||
#endif
|
||||
|
||||
#ifndef LOTTIE_CACHE_SUPPORT
|
||||
#define LOTTIE_CACHE_SUPPORT
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user