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

Nested ComponentViews have incorrect layout #28

Closed
jconst opened this issue Nov 14, 2016 · 1 comment
Closed

Nested ComponentViews have incorrect layout #28

jconst opened this issue Nov 14, 2016 · 1 comment

Comments

@jconst
Copy link
Contributor

jconst commented Nov 14, 2016

I think to make any reasonably sized app using Render, I would need the ability to nest ComponentViews inside other ComponentViews. (The strategy in the ReadMe of using a function that returns a ComponentNode is insufficient because the inner Component needs to also be able to track and update its own state.)

There are no examples that I can see in the repo, so I've taken a stab in a way that makes sense intuitively. However, there seems to be an issue that the inner view thinks the parent view's size (referenceSize) is (0,0). Here's a simplified playground:

import UIKit
import PlaygroundSupport
import Render

class InnerView: ComponentView {
    override func construct() -> ComponentNodeType {
        return ComponentNode<UIView>().configure{ view in
            view.backgroundColor = UIColor.blue
            view.style.minDimensions.height = 5
            view.style.margin = (10, 10, 10, 10, 10, 10)
            view.style.flex = 1
        }
    }
}

class OuterView: ComponentView {
    override func construct() -> ComponentNodeType {
        return ComponentNode<UIView>().configure{ view in
            view.backgroundColor = UIColor.red
        }.children([ComponentNode<InnerView>().configure{ view in
            view.backgroundColor = UIColor.green
            view.style.minDimensions.height = 50
            view.style.margin = (10, 10, 10, 10, 10, 10)
        }])
    }
}

let component = OuterView()
component.renderComponent(withSize: CGSize(width: 100, height: 100))
PlaygroundPage.current.liveView = component

With this code, I'd expect to see a blue view inside a green view inside a red view, which I do. But also, the blue view should expand to fill the size of its green container (- margin space), because flex = 1. Like so:

screen shot 2016-11-13 at 7 28 51 pm

However, the inner blue view thinks that it's parent's size is (0,0), so I instead get this:

screen shot 2016-11-13 at 7 29 46 pm

The flex property ends up being meaningless and the view just takes the size of its minDimension. (Inexplicably, though, the horizontal layout is still correct?)


My question: Is this how I should be creating nested ComponentViews? Am I missing some technique here? Could the problem be that renderComponent never gets called on the innerView, and if so, where should I put that call?

@alexdrone
Copy link
Owner

Hello!
You did nothing wrong, unfortunately I had to fix a bunch of issues related to flexbox.
I tried this today and it seems to be fixed with the new css-layout C source from fb.

The exposed flexbox API is a bit different and more consistent with the web implemenation.
This work as expected though.

class InnerView: ComponentView {
override func construct() -> ComponentNodeType {
return ComponentNode().configure{ view in
view.backgroundColor = UIColor.blue
view.css_usesFlexbox = true
view.css_minHeight = 5
view.css_setMargin(10, for: CSSEdgeTop)
view.css_setMargin(10, for: CSSEdgeLeft)
view.css_setMargin(10, for: CSSEdgeRight)
view.css_setMargin(10, for: CSSEdgeBottom)
view.css_flexGrow = 1
}
}
}

class OuterView: ComponentView {
override func construct() -> ComponentNodeType {
return ComponentNode().configure{ view in
view.backgroundColor = UIColor.red
view.css_usesFlexbox = true
}.children([ComponentNode().configure{ view in
view.backgroundColor = UIColor.green
view.css_usesFlexbox = true
view.css_minHeight = 50
view.css_setMargin(10, for: CSSEdgeTop)
view.css_setMargin(10, for: CSSEdgeLeft)
view.css_setMargin(10, for: CSSEdgeRight)
view.css_setMargin(10, for: CSSEdgeBottom)
}])
}
}

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

2 participants