I’m able to reveal my problem with this straightforward instance.
I’m utilizing AsyncDisplayKit / Texture in my iOS app.
I’ve a ASTableNode
which exhibits attributed strings. These can have pictures in them by way of NSTextAttachment
. These pictures shall be from URLs which shall be downloaded asynchronously. On this instance, for simplicity, I’m simply utilizing a picture from the Bundle
. As soon as downloaded, the NSTextAttachment
must replace its bounds to the proper side ratio of the particular picture.
The issue I’m going through is that regardless of me calling setNeedsLayout()
and layoutIfNeeded()
after updating the picture and bounds of the NSTextAttachment after getting the picture, the ASTextNode
by no means updates to indicate the picture. I’m not positive what I’m lacking.
Code:
import UIKit
import AsyncDisplayKit
class ViewController: ASDKViewController<ASDisplayNode>, ASTableDataSource {
let tableNode = ASTableNode()
override init() {
tremendous.init(node: tableNode)
tableNode.dataSource = self
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection part: Int) -> Int {
return 1
}
func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
let row = indexPath.row
return {
let node = MyCellNode(index: row, earlier than: """
Merchandise (row).
Lorem Ipsum is just dummy textual content of the printing and typesetting trade. Lorem Ipsum has been the trade's normal dummy textual content ever because the 1500s, when an unknown printer took a galley of kind and scrambled it to make a sort specimen ebook.
""",
after: """
Opposite to common perception, Lorem Ipsum just isn't merely random textual content. It has roots in a chunk of classical Latin literature from 45 BC, making it over 2000 years previous.
""")
return node
}
}
}
class MyCellNode: ASCellNode {
fileprivate var myTextNode = ASTextNode()
init(index : Int, earlier than: String, after: String) {
tremendous.init()
debugName = "Row (index)"
automaticallyManagesSubnodes = true
automaticallyRelayoutOnSafeAreaChanges = true
automaticallyRelayoutOnLayoutMarginsChanges = true
let attributedText = NSMutableAttributedString(attributedString: (earlier than+"n").formattedText())
let attachment = CustomAttachment(url: Bundle.principal.url(forResource: "check", withExtension: "png")!)
attachment.bounds = CGRect(x: 0, y: 0, width: CGFLOAT_MIN, top: CGFLOAT_MIN)
attachment.picture = UIImage()
let attachmentAttributedString = NSMutableAttributedString(attachment: attachment)
let fashion = NSMutableParagraphStyle()
fashion.alignment = .middle
attachmentAttributedString.addAttribute(.paragraphStyle, worth: fashion)
attributedText.append(attachmentAttributedString)
attributedText.append(("n"+after).formattedText())
myTextNode.attributedText = attributedText
}
override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
if let attributedText = myTextNode.attributedText {
attributedText.enumerateAttribute(NSAttributedString.Key.attachment, in: NSRange(location: 0, size: attributedText.size)) { a, vary, _ in
if let attachment = a as? CustomAttachment {
print("attachment: (attachment.bounds)")
}
}
}
let paddingToUse = 10.0
return ASInsetLayoutSpec(insets: UIEdgeInsets(high: paddingToUse, left: paddingToUse, backside: paddingToUse, proper: paddingToUse), youngster: myTextNode)
}
override func structure() {
tremendous.structure()
}
override func didEnterPreloadState() {
tremendous.didEnterPreloadState()
print("----- didEnterPreloadState: (String(describing: debugName))")
if let attributedText = myTextNode.attributedText {
attributedText.enumerateAttribute(NSAttributedString.Key.attachment, in: NSRange(location: 0, size: attributedText.size)) { a, vary, _ in
if let attachment = a as? CustomAttachment {
// print("attachment: (attachment.url)")
if let imageData = NSData(contentsOf: attachment.url), let img = UIImage(information: imageData as Information) {
print("Dimension: (img.dimension)")
attachment.picture = img
attachment.bounds = CGRect(x: 0, y: 0, width: 200, top: 200)
setNeedsLayout()
layoutIfNeeded()
}
}
}
}
}
override func didExitPreloadState() {
tremendous.didExitPreloadState()
print("----- didExitPreloadState: (String(describing: debugName))")
}
}
extension String {
func formattedText() -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSAttributedString.Key.foregroundColor : UIColor.white,NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20, weight: .regular)])
}
}
extension NSMutableAttributedString {
func addAttribute(_ identify: NSAttributedString.Key, worth: Any) {
addAttribute(identify, worth: worth, vary: NSRange(location: 0, size: size))
}
func addAttributes(_ attrs: [NSAttributedString.Key : Any]) {
addAttributes(attrs, vary: NSRange(location: 0, size: size))
}
}
class CustomAttachment: NSTextAttachment {
var url : URL
public init(url: URL) {
self.url = url
tremendous.init(information: nil, ofType: nil)
}
required init?(coder: NSCoder) {
fatalError()
}
}