如何设置子 ASNetworkImageNode 的比例

How to set the ratio of a child ASNetworkImageNode

我有一个 ASViewController 呈现 ASTableNode

我想在每行中使用一个 ASNetworkImageNode 来渲染图像。

我知道宽度/高度,所以能够正确设置比例。因此,我在图像上使用 ASRatioLayoutSpec

我遇到的问题是,我将在我的行中包含 ASNetworkImageNode 和其他子节点。

如何在我的 layoutSpecThatFits 方法中正确设置比率?

如果我改成如下:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {

    let ratio: CGFloat = props.size.height / props.size.width
    let imageRatioSpec = ASRatioLayoutSpec(ratio: ratio, child: self.imageNode)
    return imageRatioSpec

}

它工作得很好,但是我不能这样 return 任何其他子节点。

我期待的是:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {

    let ratio: CGFloat = props.size.height / props.size.width
    let imageRatioSpec = ASRatioLayoutSpec(ratio: ratio, child: self.imageNode)


    return ASStackLayoutSpec(
        direction: .horizontal,
        spacing: 16,
        justifyContent: .start,
        alignItems: .center,
        children: [imageRatioSpec, textNode] // returns image and text
    )
}

但不显示图像,或者至少不设置比例,因此图像不可见。

import AsyncDisplayKit

class FeedNodeController: ASViewController<ASTableNode> {
        var data = [
        FeedItem(url: "https://pbs.twimg.com/media/EAtM2HyXUAEXJkA.jpg", size: .init(width: 1200, height: 800)),
        FeedItem(url: "https://pbs.twimg.com/media/EAtBZzOXUAEqeNJ.jpg", size: .init(width: 680, height: 510)),
        FeedItem(url: "https://pbs.twimg.com/media/EAsxYhlXoAArJe7.jpg", size: .init(width: 680, height: 453)),
        FeedItem(url: "https://pbs.twimg.com/media/EAss0ACXoAAUtlc.jpg", size: .init(width: 1115, height: 1200))
    ]

    init() {
        super.init(node: FeedTableNode())
    }

    required init?(coder aDecoder: NSCoder) {
        return nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        node.dataSource = self
        node.delegate = self
        node.view.tableFooterView = UIView()
    }
}

extension FeedNodeController:  ASTableDataSource, ASTableDelegate {
    func numberOfSections(in tableNode: ASTableNode) -> Int {
        return 1
    }

    func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
        let props = data[indexPath.row]

        let nodeBlock: ASCellNodeBlock = { () -> ASCellNode in
            return FeedCellNode(props)
        }
        return nodeBlock
    }
}

class FeedTableNode: ASTableNode { }

class FeedCellNode: ASCellNode {

    private var props: FeedItem

    private lazy var imageNode: ASNetworkImageNode = {
        let node = ASNetworkImageNode()
        return node
    }()

    init(_ props: FeedItem) {
        self.props = props
        super.init()

        automaticallyManagesSubnodes = true
        imageNode.url = props.url
        addSubnode(imageNode)
    }

    override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {

        let ratio: CGFloat = props.size.height / props.size.width
        let imageRatioSpec = ASRatioLayoutSpec(ratio: ratio, child: self.imageNode)

        return ASStackLayoutSpec(
            direction: .horizontal,
            spacing: 16,
            justifyContent: .start,
            alignItems: .center,
            children: [imageRatioSpec]
        )
    }
}



struct FeedItem {
    var url: URL
    var size: CGSize

    init(url: String, size: CGSize) {
        self.url = URL(string: url)!
        self.size = size
    }
}

您需要将 ASStackLayoutSpec 更改为 垂直 堆栈。

   return ASStackLayoutSpec(
            direction: .vertical,
            spacing: 16,
            justifyContent: .start,
            alignItems: .center,
            children: [imageRatioSpec, textNode]
        )