TextureGroup / Texture

Smooth asynchronous user interfaces for iOS apps.

Home Page:https://texturegroup.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ASDisplayNode in ASCornerLayoutSpec in ASCellNode: preferredSize's width not working

Pranoy1c opened this issue · comments

commented

I am very new to Texture/AsyncDisplayKit. I am able to reproduce the issue with this simple code.

I basically want to show a 10x10 square at the bottom right of the ASCellNode. I am doing this via a ASDisplayNode which is being set as the corner of a ASCornerLayoutSpec. I have set the style.preferredSize of the ASDisplayNode to CGSize(width: 10, height: 10).

For some reason, the width is not working and showing up as 50% of the screen width:

enter image description here

Code:

import UIKit
import AsyncDisplayKit

class ViewController: ASDKViewController<ASDisplayNode>, ASTableDataSource {

    var tableNode = ASTableNode()

    override init() {
        super.init(node: tableNode)
        
        node.automaticallyRelayoutOnSafeAreaChanges = true
        node.automaticallyManagesSubnodes = true
        tableNode.dataSource = self
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
        return 100
    }
    
    func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
        let cellNodeBlock = { () -> ASCellNode in
            let cellNode = CellNode()
            return cellNode
        }
        
        return cellNodeBlock
    }
    
}

class CellNode: ASCellNode {
    fileprivate let titleNode = ASTextNode()
    fileprivate let savedIconNode = ASDisplayNode()
    
    
    override init() {
        super.init()
        self.automaticallyManagesSubnodes = true
        titleNode.attributedText = NSAttributedString(string: "This is my title!", attributes: [.font : UIFont.systemFont(ofSize: 20),.foregroundColor:UIColor.white])
        
        savedIconNode.isLayerBacked = true
        savedIconNode.backgroundColor = .green
        savedIconNode.style.preferredSize = CGSize(width: 10, height: 10)
    }
    
    override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
        let paddingToUse = 15.0;
        let contentView = ASInsetLayoutSpec(insets: UIEdgeInsets(top: paddingToUse, left: paddingToUse, bottom: paddingToUse, right: paddingToUse), child: ASStackLayoutSpec(direction: .horizontal, spacing: 5, justifyContent: .spaceBetween, alignItems: .notSet, children: [titleNode]))
        
        let contentViewAndSaveTriangle = ASCornerLayoutSpec(child: contentView, corner: savedIconNode, location: .bottomRight)
        
        return contentViewAndSaveTriangle
    }
}

Any idea what am I doing wrong?

ASCornerLayoutSpec is not the best solution for the cell, as part of the node will be cut off even with clipsToBounds = false:

Issue example

As an option, a combination of ASOverlayLayoutSpec and ASRelativeLayoutSpec may be suitable:

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
    let paddingToUse = 15.0;
    let contentView = ASInsetLayoutSpec(insets: UIEdgeInsets(top: paddingToUse, left: paddingToUse, bottom: paddingToUse, right: paddingToUse), child: ASStackLayoutSpec(direction: .horizontal, spacing: 5, justifyContent: .spaceBetween, alignItems: .notSet, children: [titleNode]))
    
    return ASOverlayLayoutSpec(
        child: contentView,
        overlay: ASRelativeLayoutSpec(
            horizontalPosition: .end,
            verticalPosition: .end,
            sizingOption: .minimumSize,
            child: savedIconNode
        )
    )
}

Result:

Result example