Skip to content

Commit

Permalink
fix(ios): an instance of ListView crash during layout
Browse files Browse the repository at this point in the history
(cherry picked from commit 7c54365)
  • Loading branch information
Xiaoy312 authored and mergify[bot] committed Aug 9, 2023
1 parent 55457da commit 3d0a558
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
38 changes: 38 additions & 0 deletions src/Uno.UI/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,43 @@ public static List<TResult> SelectToList<TResult>(this UIElementCollection sourc

return output;
}

/// <summary>
/// ToDictionary that doesn't throw on duplicated key. The first value is kept per key.
/// </summary>
public static Dictionary<TKey, TElement> ToDictionaryKeepFirst<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
) where TKey : notnull
{
var result = new Dictionary<TKey, TElement>();

foreach (var item in source)

Check warning on line 49 in src/Uno.UI/Extensions/EnumerableExtensions.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI/Extensions/EnumerableExtensions.cs#L49

Refactor this method to add validation of parameter 'source' before using it.
{
result.TryAdd(keySelector(item), elementSelector(item));
}

return result;
}

/// <summary>
/// ToDictionary that doesn't throw on duplicated key. The last value is kept per key.
/// </summary>
public static Dictionary<TKey, TElement> ToDictionaryKeepLast<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
) where TKey : notnull
{
var result = new Dictionary<TKey, TElement>();

foreach (var item in source)
{
result[keySelector(item)] = elementSelector(item);
}

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -557,13 +557,13 @@ private CGSize PrepareLayoutInternal(bool createLayoutInfo, bool isCollectionCha
// We are layouting after an INotifyCollectionChanged operation(s). Cache the previous element sizes, under their new index
// paths, so we can reuse them in order not to have to lay out elements with different databound sizes with their static size.
oldItemSizes = _itemLayoutInfos.SelectMany(kvp => kvp.Value)
.ToDictionary(
.ToDictionaryKeepLast(
kvp => OffsetIndexForPendingChanges(kvp.Key, NativeListViewBase.ListViewItemElementKind),
kvp => (CGSize?)kvp.Value.Size
);
oldGroupHeaderSizes = _supplementaryLayoutInfos
.UnoGetValueOrDefault(NativeListViewBase.ListViewSectionHeaderElementKind)?
.ToDictionary(
.ToDictionaryKeepLast(
kvp => OffsetIndexForPendingChanges(kvp.Key, NativeListViewBase.ListViewSectionHeaderElementKind).Section,
kvp => (CGSize?)kvp.Value.Size
);
Expand Down

0 comments on commit 3d0a558

Please sign in to comment.