fix(ios): listview scrollToIndex crash with async data (#6182)

This commit is contained in:
Manol Donev
2018-08-17 17:09:48 +03:00
committed by GitHub
parent 0f2192d4d7
commit a8d016c6d7
2 changed files with 50 additions and 7 deletions

View File

@ -759,6 +759,33 @@ export class ListViewTest extends UITest<ListView> {
TKUnit.assertEqual(lastNativeElementVisible, false, "Last element is not visible");
}
public test_scrollToIndex_should_coerce_negative_index_to_zero_index() {
var listView = this.testView;
listView.items = MANY_ITEMS;
listView.scrollToIndex(-1);
TKUnit.wait(0.1);
var firstNativeElementVisible = this.checkItemVisibleAtIndex(listView, 0);
TKUnit.assertEqual(firstNativeElementVisible, true, "first element is visible");
}
public test_scrollToIndex_should_coerce_larger_index_to_last_item_index() {
var listView = this.testView;
listView.items = MANY_ITEMS;
listView.scrollToIndex(10000);
TKUnit.wait(0.1);
var lastNativeElementVisible = this.checkItemVisibleAtIndex(listView, MANY_ITEMS.length - 1);
TKUnit.assertEqual(lastNativeElementVisible, true, "last element is visible");
}
public test_scrollToIndex_should_not_throw_if_items_not_set() {
var listView = this.testView;
listView.scrollToIndex(10000);
}
private checkItemVisibleAtIndex(listView: ListView, index: number): boolean {
return listView.isItemAtIndexVisible(index);
}

View File

@ -1,4 +1,4 @@
import { ItemEventData } from ".";
import { ItemEventData } from ".";
import {
ListViewBase, View, KeyedTemplate, Length, Observable, Color,
separatorColorProperty, itemTemplatesProperty, iosEstimatedRowHeightProperty, layout, EventData
@ -6,6 +6,7 @@ import {
import { StackLayout } from "../layouts/stack-layout";
import { ProxyViewContainer } from "../proxy-view-container";
import { profile } from "../../profiling";
import * as trace from "../../trace";
export * from "./list-view-common";
@ -261,16 +262,31 @@ export class ListView extends ListViewBase {
}
public scrollToIndex(index: number) {
if (this._ios) {
this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0),
UITableViewScrollPosition.Top, false);
}
this._scrollToIndex(index, false);
}
public scrollToIndexAnimated(index: number) {
if (this._ios) {
this._scrollToIndex(index);
}
private _scrollToIndex(index: number, animated: boolean = true) {
if (!this._ios) {
return;
}
const itemsLength = this.items ? this.items.length : 0;
// mimic Android behavior that silently coerces index values within [0, itemsLength - 1] range
if (itemsLength > 0) {
if (index < 0) {
index = 0
} else if (index >= itemsLength) {
index = itemsLength - 1;
}
this._ios.scrollToRowAtIndexPathAtScrollPositionAnimated(NSIndexPath.indexPathForItemInSection(index, 0),
UITableViewScrollPosition.Top, true);
UITableViewScrollPosition.Top, animated);
} else if (trace.isEnabled()) {
trace.write(`Cannot scroll listview to index ${index} when listview items not set`, trace.categories.Binding);
}
}