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

Scroll viewer layoutbug #2859

Merged
merged 13 commits into from
Aug 8, 2019
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"comment": "Moving picker fix",
"type": "prerelease",
"packageName": "react-native-windows",
"email": "decrowle@microsoft.com",
"commit": "8455d973a19be1d5e9bfee6329099d5657c64826",
"date": "2019-07-31T23:18:01.700Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"comment": "Clear m_needsForceLayout between calls to DoLayout",
"type": "patch",
"packageName": "react-native-windows-extended",
"email": "decrowle@microsoft.com",
"commit": "a783433937d1558283ba587db05b76ab0981a34c",
"date": "2019-08-02T20:57:41.153Z"
}
26 changes: 19 additions & 7 deletions vnext/ReactUWP/Modules/NativeUIManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,11 @@ void NativeUIManager::CreateView(
auto *pViewManager = node.GetViewManager();

if (pViewManager->RequiresYogaNode()) {
// Generate list of controls that need to have layout rerun on them.
if (const auto control = node.GetView().try_as<winrt::Control>()) {
m_controlNodes.push_back(node.m_tag);
}
decrowle marked this conversation as resolved.
Show resolved Hide resolved

auto result = m_tagsToYogaNodes.emplace(node.m_tag, make_yoga_node());
if (result.second == true) {
YGNodeRef yogaNode = result.first->second.get();
Expand Down Expand Up @@ -1011,17 +1016,24 @@ void NativeUIManager::UpdateExtraLayout(int64_t tag) {
if (shadowNode == nullptr)
return;

if (shadowNode->IsExternalLayoutDirty()) {
YGNodeRef yogaNode = GetYogaNode(tag);
if (yogaNode)
shadowNode->DoExtraLayoutPrep(yogaNode);
}

for (int64_t child : shadowNode->m_children)
for (int64_t child : shadowNode->m_children) {
UpdateExtraLayout(child);
}
}

void NativeUIManager::DoLayout() {
// Process vector of controls needing extra layout here.
const auto controlNodes = m_controlNodes;
for (const int64_t tag : controlNodes) {
ShadowNodeBase &node =
static_cast<ShadowNodeBase &>(m_host->GetShadowNodeForTag(tag));
if (node.needsForceLayout()) {
auto control = node.GetView().try_as<winrt::Control>();
decrowle marked this conversation as resolved.
Show resolved Hide resolved
control.UpdateLayout();
}
}
// Values need to be cleared from the vector before next call to DoLayout.
m_controlNodes.clear();
auto &rootTags = m_host->GetAllRootTags();
for (int64_t rootTag : rootTags) {
UpdateExtraLayout(rootTag);
Expand Down
1 change: 1 addition & 0 deletions vnext/ReactUWP/Modules/NativeUIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class NativeUIManager : public facebook::react::INativeUIManager {
std::vector<winrt::Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker>
m_sizeChangedVector;
std::vector<std::function<void()>> m_batchCompletedCallbacks;
std::vector<int64_t> m_controlNodes;

std::map<int64_t, std::weak_ptr<IXamlReactControl>> m_tagsToXamlReactControl;
};
Expand Down
21 changes: 5 additions & 16 deletions vnext/ReactUWP/Views/PickerViewManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ class PickerShadowNode : public ShadowNodeBase {
PickerShadowNode();
void createView() override;
void updateProperties(const folly::dynamic &&props) override;
bool IsExternalLayoutDirty() const override {
return m_hasNewItems;
}
void DoExtraLayoutPrep(YGNodeRef yogaNode) override;
bool needsForceLayout() override;

private:
void RepopulateItems();
Expand All @@ -40,7 +37,6 @@ class PickerShadowNode : public ShadowNodeBase {

folly::dynamic m_items;
int32_t m_selectedIndex = -1;
bool m_hasNewItems = false;

// FUTURE: remove when we can require RS5+
bool m_isEditableComboboxSupported;
Expand All @@ -55,16 +51,6 @@ PickerShadowNode::PickerShadowNode() : Super() {
L"Windows.UI.Xaml.Controls.ComboBox", L"IsEditableProperty");
}

void PickerShadowNode::DoExtraLayoutPrep(YGNodeRef yogaNode) {
if (!m_hasNewItems)
return;

m_hasNewItems = false;

auto comboBox = GetView().try_as<winrt::ComboBox>();
comboBox.UpdateLayout();
}

void PickerShadowNode::createView() {
Super::createView();
auto combobox = GetView().as<winrt::ComboBox>();
Expand Down Expand Up @@ -167,7 +153,6 @@ void PickerShadowNode::RepopulateItems() {

comboBoxItems.Append(comboboxItem);
}
m_hasNewItems = true;
}
if (m_selectedIndex < static_cast<int32_t>(m_items.size()))
combobox.SelectedIndex(m_selectedIndex);
Expand All @@ -185,6 +170,10 @@ void PickerShadowNode::RepopulateItems() {
instance.DispatchEvent(tag, "topChange", std::move(eventData));
}

bool PickerShadowNode::needsForceLayout() {
return true;
}

PickerViewManager::PickerViewManager(
const std::shared_ptr<IReactInstance> &reactInstance)
: Super(reactInstance) {}
Expand Down
4 changes: 4 additions & 0 deletions vnext/ReactUWP/Views/ShadowNodeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ void ShadowNodeBase::createView() {
m_view = GetViewManager()->CreateView(this->m_tag);
}

bool ShadowNodeBase::needsForceLayout() {
return false;
}

void ShadowNodeBase::dispatchCommand(
int64_t commandId,
const folly::dynamic &commandArgs) {
Expand Down
1 change: 1 addition & 0 deletions vnext/include/ReactUWP/Views/ShadowNodeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct REACTWINDOWS_EXPORT ShadowNodeBase : public facebook::react::ShadowNode {
virtual void AddView(ShadowNode &child, int64_t index) override;
virtual void RemoveChildAt(int64_t indexToRemove) override;
virtual void createView() override;
virtual bool needsForceLayout();
decrowle marked this conversation as resolved.
Show resolved Hide resolved

virtual void updateProperties(const folly::dynamic &&props) override;

Expand Down