Skip to content

Instantly share code, notes, and snippets.

@edudnyk
Last active July 29, 2019 21:54
Show Gist options
  • Save edudnyk/098c9cc28095efc8bbb9e8312f84a992 to your computer and use it in GitHub Desktop.
Save edudnyk/098c9cc28095efc8bbb9e8312f84a992 to your computer and use it in GitHub Desktop.
private static func animationsForAttributeDiff(forRootKey rootKey: String,
attributedStringKey: NSAttributedString.Key,
fromValue: Any?,
toValue: Any?,
in diffRange: NSRange,
attributeStates : NSMutableDictionary,
duration: TimeInterval)->[CABasicAnimation] {
var animations = [CABasicAnimation]()
let appendAnimation : (_ keyPath: String, _ from: Any?, _ to: Any?)->() =
{ (keyPath, from, to) in
let animation = CABasicAnimation(forKeyPath: keyPath,
fromValue: from,
toValue: to,
duration: duration)
animations.append(animation)
}
if attributeStates[attributedStringKey.rawValue] == nil {
attributeStates[attributedStringKey.rawValue] = NSMutableDictionary()
}
let objectDictKey = keyPath(attributedStringKey.rawValue, range: diffRange)
let objectRootKey = keyPath(rootKey, suffix: objectDictKey)
var encodingType : LKNSDictionaryCoding.Type?
if fromValue != nil,
let fromValueType = type(of: fromValue!) as? LKNSDictionaryCoding.Type {
encodingType = fromValueType
} else if toValue != nil,
let toValueType = type(of: toValue!) as? LKNSDictionaryCoding.Type {
encodingType = toValueType
}
if encodingType != nil {
let fromObjectAttrs = encodingType!.lk_dictEncode(object: fromValue as AnyObject)
let toObjectAttrs = encodingType!.lk_dictEncode(object: toValue as AnyObject)
/// Setting of initial interpolation value into interpolation context
attributeStates.setValue(fromObjectAttrs, forKeyPath:objectDictKey)
self.enumerateDiffs(leftDictionary: fromObjectAttrs,
rightDictionary: toObjectAttrs,
using: { (key, from, to) in
let kPath = keyPath(objectRootKey, suffix: key)
appendAnimation(kPath, from, to)
})
} else if let attrDict = attributeStates[attributedStringKey.rawValue] as? NSMutableDictionary {
attrDict[NSStringFromRange(diffRange)] = fromValue
appendAnimation(objectRootKey, fromValue, toValue)
}
return animations
}
private static func enumerateDiffs(leftDictionary: NSDictionary,
rightDictionary: NSDictionary,
using block: (_ key: String,
_ fromValue: Any?,
_ toValue: Any?)->()) {
let totalKeySet = NSMutableSet(array: leftDictionary.allKeys)
totalKeySet.addObjects(from: rightDictionary.allKeys)
totalKeySet.forEach { (key) in
let fromValue = leftDictionary[key]
let toValue = rightDictionary[key]
if (fromValue != nil || toValue != nil) &&
!(fromValue as AnyObject).isEqual(toValue) {
if let fromValueDict = fromValue as? NSDictionary,
let toValueDict = toValue as? NSDictionary {
self.enumerateDiffs(leftDictionary: fromValueDict,
rightDictionary: toValueDict,
using: { (keySuffix, from, to) in
block(keyPath(key, suffix: keySuffix), from, to)
})
} else {
block(key as! String, fromValue, toValue)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment