Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child already has a owner, it must be removed first. #237

Closed
srv7 opened this issue Nov 23, 2023 · 6 comments
Closed

Child already has a owner, it must be removed first. #237

srv7 opened this issue Nov 23, 2023 · 6 comments

Comments

@srv7
Copy link

srv7 commented Nov 23, 2023

func setup(_ x: String) {
        subviews.forEach { $0.removeFromSuperview() }
        flex.padding(15).define { flex in
            flex.addItem().width(100%).direction(.row).justifyContent(.spaceAround)
                .define { flex in
                    for i in 1 ... 4 {
                        let label = UILabel()
                        label.text = "\(x)--\(i)"
                        flex.addItem(label).height(44).width(20%)
                    }
                }

            flex.addItem().height(60).marginTop(15).direction(.row).alignItems(.stretch).define { flex in
                flex.addItem(btnA).grow(1).shrink(1)
                flex.addItem().width(11)
                flex.addItem(btnB).grow(1).shrink(1)
            }
        }
    }

call setup method twice and then crash.

[email protected]
function YGAttachNodesFromViewHierachy(UIView *const view)

[email protected]
function YGAttachNodesFromViewHierachy(UIView *const view)

so, why remove these code

@srv7
Copy link
Author

srv7 commented Nov 23, 2023

import FlexLayout
import UIKit

class ViewController: UIViewController {
    
    let container = UIView()
    
    lazy var kindView: AKindView = {
        let view = AKindView()
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "set", style: .plain, target: self, action: #selector(changeAction))
        view.addSubview(container)
        container.frame = view.bounds
        container.flex.paddingTop(100).direction(.column).justifyContent(.center).alignItems(.stretch).define { flex in
            flex.addItem(kindView)
        }
        kindView.setup("A")
        container.flex.layout(mode: .adjustHeight)
    }
    @objc func changeAction() {
        kindView.setup("B")
        container.flex.layout(mode: .adjustHeight)
    }
}
import FlexLayout
import UIKit

class AKindView: UIView {
    lazy var btnA: UIButton = {
        let btn = UIButton()
        btn.setTitle("ABC", for: .normal)
        btn.backgroundColor = .orange
        return btn
    }()

    lazy var btnB: UIButton = {
        let btn = UIButton()
        btn.setTitle("DEF", for: .normal)
        btn.backgroundColor = .orange
        return btn
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setup(_ x: String) {
        subviews.forEach { $0.removeFromSuperview() }
        flex.padding(15).define { flex in
            flex.addItem().width(100%).direction(.row).justifyContent(.spaceAround)
                .define { flex in
                    for i in 1 ... 4 {
                        let label = UILabel()
                        label.text = "\(x)--\(i)"
                        flex.addItem(label).height(44).width(20%)
                    }
                }

            flex.addItem().height(60).marginTop(15).direction(.row).alignItems(.stretch).define { flex in
                flex.addItem(btnA).grow(1).shrink(1)
                flex.addItem().width(11)
                flex.addItem(btnB).grow(1).shrink(1)
            }
        }
    }
}

@MQLiu
Copy link

MQLiu commented Jan 2, 2024

Same issue, has anyone fixed it yet?

@kennethpu
Copy link

The issue here is that when setup() is called multiple times btnA and btnB wind up moving between different superviews. This means their corresponding node still has an associated parent when YGNodeInsertChild() is called, triggering the assert.

It looks like we previously had modified YGLayout to clean up these parent references (c303faa) but this was overwritten when we updated to Yoga 2.0. I have a PR (#242) to restore these lines and keep us from hitting the assert.

@MQLiu
Copy link

MQLiu commented Jan 10, 2024 via email

@lucdion
Copy link
Member

lucdion commented Jan 11, 2024

The fix will be merged today.

@lucdion
Copy link
Member

lucdion commented Jan 11, 2024

The fix has been released.

@lucdion lucdion closed this as completed Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants