使用AsyncDisplayKit/Texture时,ASCellNode如何实现带animated参数的选中/高亮?
关于ASCellNode选中/高亮逻辑的问题解答
一、为什么ASCellNode用属性而非带animated参数的方法?
Texture(原AsyncDisplayKit)的设计核心是异步渲染+节点树状态驱动,和UIKit的UIView生命周期逻辑差异明显:
- UITableViewCell的
setSelected(_:animated:)等方法是UIKit基于视图命令式调用的设计,直接触发状态变更和动画; - ASCellNode则采用属性观察+内部状态统一管理的模式,
isHighlighted/isSelected属性是对外暴露的状态入口,内部的状态变更逻辑(包括动画)由框架统一调度,避免命令式调用带来的状态不一致问题,更贴合节点树的异步渲染特性。
注:ASCellNode其实也开放了带animated参数的setHighlighted(_:animated:)和setSelected(_:animated:)方法,并非只能重写属性。
二、如何在ASCellNode中获取animated参数,实现仅用户交互时动画?
直接重写ASCellNode的setHighlighted(_:animated:)和setSelected(_:animated:)方法即可,这两个方法的animated参数会在不同场景下传入对应值:
- 用户交互触发高亮/选中时,
animated为true; - 代码调用(如
ASTableNode.selectRow)时,animated为你传入的参数值。
示例代码:
class CustomCellNode: ASCellNode { override init() { super.init() self.selectionStyle = .default } override func setHighlighted(_ highlighted: Bool, animated: Bool) { super.setHighlighted(highlighted, animated: animated) let updateAction: () -> Void = { self.backgroundColor = highlighted ? UIColor.lightGray.withAlphaComponent(0.5) : .white } if animated { UIView.animate(withDuration: 0.2, animations: updateAction) } else { updateAction() } } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) let updateAction: () -> Void = { self.transform = selected ? CGAffineTransform(scaleX: 0.98, y: 0.98) : .identity } if animated { UIView.animate(withDuration: 0.2, animations: updateAction) } else { updateAction() } } }
如果一定要通过属性重写实现,可以结合highlightAnimationDuration和selectionAnimationDuration判断:用户交互触发时,这两个属性值大于0;代码触发时为0。示例:
override var isHighlighted: Bool { didSet { let shouldAnimate = highlightAnimationDuration > 0 // 后续逻辑同上 } }
三、ASTableNode.selectRow的animated参数不生效的解决办法
出现这个问题通常有以下几个原因,对应解决方式:
- 未自定义选中动画逻辑:默认ASCellNode没有选中动画,需要你在
setSelected(_:animated:)方法中自行实现动画逻辑(参考上面的示例); - 节点未完成渲染:如果调用
selectRow时目标节点还未异步加载完成,动画可能无法触发。可以延迟调用,或者在tableNode(_:willDisplay:forRowAt:)代理方法中执行选中操作; - 配置项冲突:检查
ASTableNode的allowsSelection是否设为true,以及单元格节点的selectionStyle是否为.none(如果是.none,默认不会触发选中状态变更)。
内容的提问来源于stack exchange,提问作者sudoExclamationExclamation
相关产品推荐
相关产品推荐

