Texture icon indicating copy to clipboard operation
Texture copied to clipboard

safeAreaInset not correctly pass to child node

Open jeffersonsetiawan opened this issue 4 years ago • 2 comments

What

The SafeAreaInset of children node is not same as parent when add/change the node. as you can see in the video, once we change the rootNode to NodeB, the safeAreaInset for node B is 0 (reflected by button position is different)

Video

https://user-images.githubusercontent.com/14871122/133426120-010a119d-8d30-49fb-a573-576e68028145.mov

Code

class ChangeNodeVC: ASDKViewController<ASDisplayNode> {
    private var rootNode: ASDisplayNode = NodeA()
    override init() {
        super.init(node: ASDisplayNode())
        node.automaticallyManagesSubnodes = true
        node.automaticallyRelayoutOnSafeAreaChanges = true
        node.layoutSpecBlock = { [weak self] _, _ in
            guard let self = self else { return ASLayoutSpec() }
            return ASWrapperLayoutSpec(layoutElement: self.rootNode)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
       // simulate change the node after 2 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.rootNode = NodeB()
            self.node.setNeedsLayout()
        }
    }
}
// Node
class NodeA: ASDisplayNode {
    private let button = ASButtonNode()

    override init() {
        super.init()
        automaticallyManagesSubnodes = true
        automaticallyRelayoutOnSafeAreaChanges = true
        button.setAttributedTitle(NSAttributedString(string: "HELLO WORLD FROM NODE A!"), for: .normal)
        button.backgroundColor = .blue
        backgroundColor = .red
    }

    override func layoutSpecThatFits(_: ASSizeRange) -> ASLayoutSpec {
        let relative = ASRelativeLayoutSpec(horizontalPosition: .center, verticalPosition: .end, sizingOption: .minimumSize, child: button)
        return ASInsetLayoutSpec(insets: .init(top: 0, left: 0, bottom: safeAreaInsets.bottom, right: 0), child: relative)
    }
}

class NodeB: ASDisplayNode {
    private let button = ASButtonNode()

    override init() {
        super.init()
        automaticallyManagesSubnodes = true
        automaticallyRelayoutOnSafeAreaChanges = true
        button.setAttributedTitle(NSAttributedString(string: "HELLO WORLD FROM NODE B!"), for: .normal)
        button.backgroundColor = .blue
        backgroundColor = .green
    }

    override func layoutSpecThatFits(_: ASSizeRange) -> ASLayoutSpec {
        print("<<< NodeB safeAreaInsets: ", safeAreaInsets.bottom)
        let relative = ASRelativeLayoutSpec(horizontalPosition: .center, verticalPosition: .end, sizingOption: .minimumSize, child: button)
        return ASInsetLayoutSpec(insets: .init(top: 0, left: 0, bottom: safeAreaInsets.bottom, right: 0), child: relative)
    }
}

Using Texture 3 Xcode 12.4/12.5, iOS 14.4+

jeffersonsetiawan avatar Sep 15 '21 11:09 jeffersonsetiawan

Did you find a solution?

Pranoy1c avatar May 05 '24 06:05 Pranoy1c

Did you find a solution?

I fix it by getting the safeAreaInset from the top viewcontroller, not from self

jeffersonsetiawan avatar May 07 '24 02:05 jeffersonsetiawan