I’m able to show my difficulty with this easy instance.
I’m utilizing AsyncDisplayKit / Texture in my iOS app.
I’ve a ASTableNode
which exhibits attributed strings. These could have photographs in them through NSTextAttachment
. These photographs 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 facet 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 certain 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 solely 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 kind specimen guide.
""",
after: """
Opposite to in style perception, Lorem Ipsum will not be 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.major.url(forResource: "take a look at", withExtension: "png")!)
attachment.bounds = CGRect(x: 0, y: 0, width: CGFLOAT_MIN, peak: CGFLOAT_MIN)
attachment.picture = UIImage()
let attachmentAttributedString = NSMutableAttributedString(attachment: attachment)
let type = NSMutableParagraphStyle()
type.alignment = .middle
attachmentAttributedString.addAttribute(.paragraphStyle, worth: type)
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), little one: 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, peak: 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()
}
}