mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
fix(ios): listview scrollToIndex crash with async data (#6182)
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user