@nativescript/core 9.0.0-alpha.24 → 9.0.0-alpha.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/application/application-common.d.ts +29 -10
  2. package/application/application-common.js +58 -5
  3. package/application/application-common.js.map +1 -1
  4. package/application/application-interfaces.d.ts +10 -0
  5. package/application/application-shims.d.ts +27 -0
  6. package/application/application-shims.js +27 -0
  7. package/application/application-shims.js.map +1 -1
  8. package/application/application.android.d.ts +12 -2
  9. package/application/application.android.js +418 -342
  10. package/application/application.android.js.map +1 -1
  11. package/application/application.d.ts +8 -1
  12. package/application/application.ios.d.ts +16 -1
  13. package/application/application.ios.js +59 -21
  14. package/application/application.ios.js.map +1 -1
  15. package/application/helpers.android.d.ts +0 -9
  16. package/application/helpers.android.js +0 -54
  17. package/application/helpers.android.js.map +1 -1
  18. package/application/helpers.d.ts +0 -10
  19. package/application/helpers.ios.d.ts +0 -19
  20. package/application/helpers.ios.js +0 -38
  21. package/application/helpers.ios.js.map +1 -1
  22. package/config/config.interface.d.ts +21 -0
  23. package/connectivity/index.android.js +25 -25
  24. package/connectivity/index.android.js.map +1 -1
  25. package/core-types/index.d.ts +77 -63
  26. package/core-types/index.js +10 -1
  27. package/core-types/index.js.map +1 -1
  28. package/core-types/validators.js +12 -6
  29. package/core-types/validators.js.map +1 -1
  30. package/data/observable/index.d.ts +2 -1
  31. package/data/observable/index.js +31 -19
  32. package/data/observable/index.js.map +1 -1
  33. package/fps-meter/fps-native.ios.js +1 -1
  34. package/fps-meter/fps-native.ios.js.map +1 -1
  35. package/http/http-request/index.ios.js +1 -1
  36. package/http/http-request/index.ios.js.map +1 -1
  37. package/image-source/index.d.ts +2 -2
  38. package/index.js +0 -1
  39. package/index.js.map +1 -1
  40. package/package.json +1 -1
  41. package/platform/screen/index.d.ts +5 -0
  42. package/platforms/android/widgets-release.aar +0 -0
  43. package/references.d.ts +1 -1
  44. package/timer/index.ios.js +1 -1
  45. package/timer/index.ios.js.map +1 -1
  46. package/ui/action-bar/index.android.js +18 -18
  47. package/ui/action-bar/index.android.js.map +1 -1
  48. package/ui/action-bar/index.ios.js +2 -4
  49. package/ui/action-bar/index.ios.js.map +1 -1
  50. package/ui/animation/index.ios.js +2 -3
  51. package/ui/animation/index.ios.js.map +1 -1
  52. package/ui/button/index.android.js +20 -20
  53. package/ui/button/index.android.js.map +1 -1
  54. package/ui/button/index.ios.d.ts +2 -1
  55. package/ui/button/index.ios.js +28 -10
  56. package/ui/button/index.ios.js.map +1 -1
  57. package/ui/core/control-state-change/index.ios.js +1 -1
  58. package/ui/core/control-state-change/index.ios.js.map +1 -1
  59. package/ui/core/view/index.android.d.ts +6 -6
  60. package/ui/core/view/index.android.js +337 -455
  61. package/ui/core/view/index.android.js.map +1 -1
  62. package/ui/core/view/index.d.ts +18 -5
  63. package/ui/core/view/index.ios.d.ts +10 -2
  64. package/ui/core/view/index.ios.js +99 -46
  65. package/ui/core/view/index.ios.js.map +1 -1
  66. package/ui/core/view/view-common.d.ts +46 -12
  67. package/ui/core/view/view-common.js +28 -0
  68. package/ui/core/view/view-common.js.map +1 -1
  69. package/ui/core/view/view-helper/index.d.ts +5 -0
  70. package/ui/core/view/view-helper/index.ios.d.ts +5 -4
  71. package/ui/core/view/view-helper/index.ios.js +20 -23
  72. package/ui/core/view/view-helper/index.ios.js.map +1 -1
  73. package/ui/core/view/view-helper/view-helper-common.js +7 -0
  74. package/ui/core/view/view-helper/view-helper-common.js.map +1 -1
  75. package/ui/core/view/view-interfaces.d.ts +3 -0
  76. package/ui/core/view-base/index.d.ts +4 -0
  77. package/ui/core/view-base/index.js +4 -0
  78. package/ui/core/view-base/index.js.map +1 -1
  79. package/ui/date-picker/index.android.js +38 -38
  80. package/ui/date-picker/index.android.js.map +1 -1
  81. package/ui/date-picker/index.ios.js +1 -1
  82. package/ui/date-picker/index.ios.js.map +1 -1
  83. package/ui/editable-text-base/index.android.js +34 -34
  84. package/ui/editable-text-base/index.android.js.map +1 -1
  85. package/ui/frame/fragment.transitions.android.d.ts +2 -1
  86. package/ui/frame/fragment.transitions.android.js +106 -104
  87. package/ui/frame/fragment.transitions.android.js.map +1 -1
  88. package/ui/frame/fragment.transitions.d.ts +3 -2
  89. package/ui/frame/index.android.js +57 -4
  90. package/ui/frame/index.android.js.map +1 -1
  91. package/ui/frame/index.ios.d.ts +2 -1
  92. package/ui/frame/index.ios.js +83 -43
  93. package/ui/frame/index.ios.js.map +1 -1
  94. package/ui/gestures/index.android.js +129 -130
  95. package/ui/gestures/index.android.js.map +1 -1
  96. package/ui/gestures/index.ios.js +3 -5
  97. package/ui/gestures/index.ios.js.map +1 -1
  98. package/ui/gestures/touch-manager.js +32 -32
  99. package/ui/gestures/touch-manager.js.map +1 -1
  100. package/ui/image/index.android.js +19 -19
  101. package/ui/image/index.android.js.map +1 -1
  102. package/ui/image-cache/index.android.js +12 -14
  103. package/ui/image-cache/index.android.js.map +1 -1
  104. package/ui/image-cache/index.ios.js +6 -6
  105. package/ui/image-cache/index.ios.js.map +1 -1
  106. package/ui/index.d.ts +2 -1
  107. package/ui/index.js +1 -0
  108. package/ui/index.js.map +1 -1
  109. package/ui/label/index.android.js +4 -1
  110. package/ui/label/index.android.js.map +1 -1
  111. package/ui/label/index.ios.d.ts +2 -1
  112. package/ui/label/index.ios.js +12 -2
  113. package/ui/label/index.ios.js.map +1 -1
  114. package/ui/layouts/flexbox-layout/index.ios.js +3 -6
  115. package/ui/layouts/flexbox-layout/index.ios.js.map +1 -1
  116. package/ui/layouts/index.d.ts +2 -0
  117. package/ui/layouts/index.js +2 -0
  118. package/ui/layouts/index.js.map +1 -1
  119. package/ui/layouts/liquid-glass/index.android.d.ts +5 -0
  120. package/ui/layouts/liquid-glass/index.android.js +8 -0
  121. package/ui/layouts/liquid-glass/index.android.js.map +1 -0
  122. package/ui/layouts/liquid-glass/index.d.ts +10 -0
  123. package/ui/layouts/liquid-glass/index.ios.d.ts +10 -0
  124. package/ui/layouts/liquid-glass/index.ios.js +59 -0
  125. package/ui/layouts/liquid-glass/index.ios.js.map +1 -0
  126. package/ui/layouts/liquid-glass/liquid-glass-common.d.ts +3 -0
  127. package/ui/layouts/liquid-glass/liquid-glass-common.js +4 -0
  128. package/ui/layouts/liquid-glass/liquid-glass-common.js.map +1 -0
  129. package/ui/layouts/liquid-glass-container/index.android.d.ts +3 -0
  130. package/ui/layouts/liquid-glass-container/index.android.js +4 -0
  131. package/ui/layouts/liquid-glass-container/index.android.js.map +1 -0
  132. package/ui/layouts/liquid-glass-container/index.d.ts +3 -0
  133. package/ui/layouts/liquid-glass-container/index.ios.d.ts +14 -0
  134. package/ui/layouts/liquid-glass-container/index.ios.js +121 -0
  135. package/ui/layouts/liquid-glass-container/index.ios.js.map +1 -0
  136. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.d.ts +4 -0
  137. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js +5 -0
  138. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js.map +1 -0
  139. package/ui/layouts/stack-layout/index.ios.js +6 -0
  140. package/ui/layouts/stack-layout/index.ios.js.map +1 -1
  141. package/ui/list-picker/index.android.js +35 -35
  142. package/ui/list-picker/index.android.js.map +1 -1
  143. package/ui/list-picker/index.ios.js +2 -2
  144. package/ui/list-picker/index.ios.js.map +1 -1
  145. package/ui/list-view/index.android.d.ts +26 -1
  146. package/ui/list-view/index.android.js +765 -129
  147. package/ui/list-view/index.android.js.map +1 -1
  148. package/ui/list-view/index.d.ts +127 -0
  149. package/ui/list-view/index.ios.d.ts +34 -2
  150. package/ui/list-view/index.ios.js +557 -21
  151. package/ui/list-view/index.ios.js.map +1 -1
  152. package/ui/list-view/list-view-common.d.ts +22 -1
  153. package/ui/list-view/list-view-common.js +85 -0
  154. package/ui/list-view/list-view-common.js.map +1 -1
  155. package/ui/page/index.ios.js +25 -64
  156. package/ui/page/index.ios.js.map +1 -1
  157. package/ui/scroll-view/index.d.ts +1 -1
  158. package/ui/scroll-view/index.ios.d.ts +2 -0
  159. package/ui/scroll-view/index.ios.js +31 -12
  160. package/ui/scroll-view/index.ios.js.map +1 -1
  161. package/ui/scroll-view/scroll-view-common.d.ts +3 -8
  162. package/ui/scroll-view/scroll-view-common.js +4 -4
  163. package/ui/scroll-view/scroll-view-common.js.map +1 -1
  164. package/ui/search-bar/index.android.js +48 -52
  165. package/ui/search-bar/index.android.js.map +1 -1
  166. package/ui/search-bar/index.ios.js +3 -6
  167. package/ui/search-bar/index.ios.js.map +1 -1
  168. package/ui/segmented-bar/index.android.js +56 -58
  169. package/ui/segmented-bar/index.android.js.map +1 -1
  170. package/ui/segmented-bar/index.ios.js +1 -1
  171. package/ui/segmented-bar/index.ios.js.map +1 -1
  172. package/ui/slider/index.android.js +23 -25
  173. package/ui/slider/index.android.js.map +1 -1
  174. package/ui/slider/index.ios.js +2 -2
  175. package/ui/slider/index.ios.js.map +1 -1
  176. package/ui/split-view/index.android.d.ts +4 -0
  177. package/ui/split-view/index.android.js +4 -0
  178. package/ui/split-view/index.android.js.map +1 -0
  179. package/ui/split-view/index.d.ts +11 -0
  180. package/ui/split-view/index.ios.d.ts +39 -0
  181. package/ui/split-view/index.ios.js +368 -0
  182. package/ui/split-view/index.ios.js.map +1 -0
  183. package/ui/split-view/split-view-common.d.ts +51 -0
  184. package/ui/split-view/split-view-common.js +111 -0
  185. package/ui/split-view/split-view-common.js.map +1 -0
  186. package/ui/styling/background-common.d.ts +4 -4
  187. package/ui/styling/background-common.js +8 -8
  188. package/ui/styling/background-common.js.map +1 -1
  189. package/ui/styling/background.d.ts +0 -3
  190. package/ui/styling/background.ios.d.ts +2 -1
  191. package/ui/styling/background.ios.js +47 -38
  192. package/ui/styling/background.ios.js.map +1 -1
  193. package/ui/styling/css-utils.d.ts +1 -0
  194. package/ui/styling/css-utils.js +15 -4
  195. package/ui/styling/css-utils.js.map +1 -1
  196. package/ui/styling/style/index.d.ts +3 -1
  197. package/ui/styling/style/index.js.map +1 -1
  198. package/ui/styling/style-properties.d.ts +1 -0
  199. package/ui/styling/style-properties.js +30 -11
  200. package/ui/styling/style-properties.js.map +1 -1
  201. package/ui/switch/index.android.js +18 -18
  202. package/ui/switch/index.android.js.map +1 -1
  203. package/ui/switch/index.ios.d.ts +1 -0
  204. package/ui/switch/index.ios.js +62 -12
  205. package/ui/switch/index.ios.js.map +1 -1
  206. package/ui/tab-view/index.android.js +185 -187
  207. package/ui/tab-view/index.android.js.map +1 -1
  208. package/ui/tab-view/index.d.ts +17 -1
  209. package/ui/tab-view/index.ios.d.ts +13 -5
  210. package/ui/tab-view/index.ios.js +253 -49
  211. package/ui/tab-view/index.ios.js.map +1 -1
  212. package/ui/tab-view/tab-view-common.d.ts +14 -0
  213. package/ui/tab-view/tab-view-common.js +15 -0
  214. package/ui/tab-view/tab-view-common.js.map +1 -1
  215. package/ui/text-base/index.android.d.ts +2 -1
  216. package/ui/text-base/index.android.js +133 -101
  217. package/ui/text-base/index.android.js.map +1 -1
  218. package/ui/text-base/index.d.ts +5 -0
  219. package/ui/text-base/index.ios.js +12 -18
  220. package/ui/text-base/index.ios.js.map +1 -1
  221. package/ui/text-base/text-base-common.d.ts +2 -1
  222. package/ui/text-base/text-base-common.js +1 -0
  223. package/ui/text-base/text-base-common.js.map +1 -1
  224. package/ui/text-field/index.ios.d.ts +2 -1
  225. package/ui/text-field/index.ios.js +9 -5
  226. package/ui/text-field/index.ios.js.map +1 -1
  227. package/ui/text-view/index.ios.d.ts +2 -1
  228. package/ui/text-view/index.ios.js +12 -7
  229. package/ui/text-view/index.ios.js.map +1 -1
  230. package/ui/time-picker/index.android.js +21 -21
  231. package/ui/time-picker/index.android.js.map +1 -1
  232. package/ui/time-picker/index.ios.js +1 -1
  233. package/ui/time-picker/index.ios.js.map +1 -1
  234. package/ui/transition/fade-transition.ios.js +5 -6
  235. package/ui/transition/fade-transition.ios.js.map +1 -1
  236. package/ui/transition/modal-transition.ios.js +19 -26
  237. package/ui/transition/modal-transition.ios.js.map +1 -1
  238. package/ui/transition/page-transition.android.js +3 -12
  239. package/ui/transition/page-transition.android.js.map +1 -1
  240. package/ui/transition/page-transition.ios.js +19 -25
  241. package/ui/transition/page-transition.ios.js.map +1 -1
  242. package/ui/transition/slide-transition.ios.js +5 -6
  243. package/ui/transition/slide-transition.ios.js.map +1 -1
  244. package/ui/web-view/index.android.js +58 -62
  245. package/ui/web-view/index.android.js.map +1 -1
  246. package/ui/web-view/index.ios.js +18 -18
  247. package/ui/web-view/index.ios.js.map +1 -1
  248. package/utils/common.d.ts +3 -1
  249. package/utils/common.js +9 -3
  250. package/utils/common.js.map +1 -1
  251. package/utils/index.d.ts +6 -0
  252. package/utils/layout-helper/index.android.d.ts +1 -0
  253. package/utils/layout-helper/index.android.js +9 -0
  254. package/utils/layout-helper/index.android.js.map +1 -1
  255. package/utils/layout-helper/index.d.ts +5 -0
  256. package/utils/layout-helper/index.ios.d.ts +1 -0
  257. package/utils/layout-helper/index.ios.js +4 -0
  258. package/utils/layout-helper/index.ios.js.map +1 -1
  259. package/utils/native-helper-for-android.d.ts +14 -3
  260. package/utils/native-helper-for-android.js +57 -54
  261. package/utils/native-helper-for-android.js.map +1 -1
  262. package/utils/native-helper.android.d.ts +3 -3
  263. package/utils/native-helper.android.js +2 -2
  264. package/utils/native-helper.android.js.map +1 -1
  265. package/utils/native-helper.d.ts +22 -5
  266. package/utils/native-helper.ios.js +20 -20
  267. package/utils/native-helper.ios.js.map +1 -1
@@ -1,40 +1,40 @@
1
- import { ListViewBase, separatorColorProperty, itemTemplatesProperty, iosEstimatedRowHeightProperty } from './list-view-common';
1
+ import { ListViewBase, separatorColorProperty, itemTemplatesProperty, iosEstimatedRowHeightProperty, stickyHeaderProperty, stickyHeaderTemplateProperty, stickyHeaderHeightProperty, sectionedProperty, showSearchProperty, searchAutoHideProperty } from './list-view-common';
2
2
  import { View } from '../core/view';
3
3
  import { Length } from '../styling/length-shared';
4
4
  import { Observable } from '../../data/observable';
5
5
  import { Color } from '../../color';
6
6
  import { layout } from '../../utils';
7
+ import { SDK_VERSION } from '../../utils/constants';
7
8
  import { StackLayout } from '../layouts/stack-layout';
8
9
  import { ProxyViewContainer } from '../proxy-view-container';
9
10
  import { profile } from '../../profiling';
10
11
  import { Trace } from '../../trace';
12
+ import { Builder } from '../builder';
13
+ import { Label } from '../label';
14
+ import { isFunction } from '../../utils/types';
11
15
  export * from './list-view-common';
12
16
  const ITEMLOADING = ListViewBase.itemLoadingEvent;
13
17
  const LOADMOREITEMS = ListViewBase.loadMoreItemsEvent;
14
18
  const ITEMTAP = ListViewBase.itemTapEvent;
15
19
  const DEFAULT_HEIGHT = 44;
16
20
  const infinity = layout.makeMeasureSpec(0, layout.UNSPECIFIED);
17
- var ListViewCell = /** @class */ (function (_super) {
21
+ var ListViewCell = (function (_super) {
18
22
  __extends(ListViewCell, _super);
19
23
  function ListViewCell() {
20
24
  return _super !== null && _super.apply(this, arguments) || this;
21
25
  }
22
26
  ListViewCell.initWithEmptyBackground = function () {
23
27
  var cell = ListViewCell.new();
24
- // Clear background by default - this will make cells transparent
25
28
  cell.backgroundColor = UIColor.clearColor;
26
29
  return cell;
27
30
  };
28
31
  ListViewCell.prototype.initWithStyleReuseIdentifier = function (style, reuseIdentifier) {
29
32
  var cell = _super.prototype.initWithStyleReuseIdentifier.call(this, style, reuseIdentifier);
30
- // Clear background by default - this will make cells transparent
31
33
  cell.backgroundColor = UIColor.clearColor;
32
34
  return cell;
33
35
  };
34
36
  ListViewCell.prototype.willMoveToSuperview = function (newSuperview) {
35
37
  var parent = (this.view ? this.view.parent : null);
36
- // When inside ListView and there is no newSuperview this cell is
37
- // removed from native visual tree so we remove it from our tree too.
38
38
  if (parent && !newSuperview) {
39
39
  parent._removeContainer(this);
40
40
  }
@@ -48,11 +48,42 @@ var ListViewCell = /** @class */ (function (_super) {
48
48
  });
49
49
  return ListViewCell;
50
50
  }(UITableViewCell));
51
+ var ListViewHeaderCell = (function (_super) {
52
+ __extends(ListViewHeaderCell, _super);
53
+ function ListViewHeaderCell() {
54
+ return _super !== null && _super.apply(this, arguments) || this;
55
+ }
56
+ ListViewHeaderCell.initWithEmptyBackground = function () {
57
+ var cell = ListViewHeaderCell.new();
58
+ cell.backgroundColor = UIColor.clearColor;
59
+ return cell;
60
+ };
61
+ ListViewHeaderCell.prototype.initWithReuseIdentifier = function (reuseIdentifier) {
62
+ var cell = _super.prototype.initWithReuseIdentifier.call(this, reuseIdentifier);
63
+ cell.backgroundColor = UIColor.clearColor;
64
+ return cell;
65
+ };
66
+ ListViewHeaderCell.prototype.willMoveToSuperview = function (newSuperview) {
67
+ var parent = (this.view ? this.view.parent : null);
68
+ if (parent && !newSuperview) {
69
+ parent._removeHeaderContainer(this);
70
+ }
71
+ };
72
+ Object.defineProperty(ListViewHeaderCell.prototype, "view", {
73
+ get: function () {
74
+ return this.owner ? this.owner.deref() : null;
75
+ },
76
+ enumerable: true,
77
+ configurable: true
78
+ });
79
+ return ListViewHeaderCell;
80
+ }(UITableViewHeaderFooterView));
51
81
  function notifyForItemAtIndex(listView, cell, view, eventName, indexPath) {
52
82
  const args = {
53
83
  eventName: eventName,
54
84
  object: listView,
55
85
  index: indexPath.row,
86
+ section: indexPath.section,
56
87
  view: view,
57
88
  ios: cell,
58
89
  android: undefined,
@@ -60,7 +91,7 @@ function notifyForItemAtIndex(listView, cell, view, eventName, indexPath) {
60
91
  listView.notify(args);
61
92
  return args;
62
93
  }
63
- var DataSource = /** @class */ (function (_super) {
94
+ var DataSource = (function (_super) {
64
95
  __extends(DataSource, _super);
65
96
  function DataSource() {
66
97
  return _super !== null && _super.apply(this, arguments) || this;
@@ -70,14 +101,33 @@ var DataSource = /** @class */ (function (_super) {
70
101
  dataSource._owner = owner;
71
102
  return dataSource;
72
103
  };
104
+ DataSource.prototype.numberOfSectionsInTableView = function (tableView) {
105
+ var _a;
106
+ var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
107
+ if (!owner) {
108
+ return 1;
109
+ }
110
+ var sections = owner._getSectionCount();
111
+ if (Trace.isEnabled()) {
112
+ Trace.write("ListView: numberOfSections = ".concat(sections, " (sectioned: ").concat(owner.sectioned, ")"), Trace.categories.Debug);
113
+ }
114
+ return sections;
115
+ };
73
116
  DataSource.prototype.tableViewNumberOfRowsInSection = function (tableView, section) {
74
117
  var _a;
75
118
  var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
76
- return owner && owner.items ? owner.items.length : 0;
119
+ if (!owner) {
120
+ return 0;
121
+ }
122
+ var sectionItems = owner._getItemsInSection(section);
123
+ var rowCount = sectionItems ? sectionItems.length : 0;
124
+ if (Trace.isEnabled()) {
125
+ Trace.write("ListView: numberOfRows in section ".concat(section, " = ").concat(rowCount), Trace.categories.Debug);
126
+ }
127
+ return rowCount;
77
128
  };
78
129
  DataSource.prototype.tableViewCellForRowAtIndexPath = function (tableView, indexPath) {
79
130
  var _a;
80
- // We call this method because ...ForIndexPath calls tableViewHeightForRowAtIndexPath immediately (before we can prepare and measure it).
81
131
  var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
82
132
  var cell;
83
133
  if (owner) {
@@ -86,8 +136,6 @@ var DataSource = /** @class */ (function (_super) {
86
136
  owner._prepareCell(cell, indexPath);
87
137
  var cellView = cell.view;
88
138
  if (cellView && cellView.isLayoutRequired) {
89
- // Arrange cell views. We do it here instead of _layoutCell because _layoutCell is called
90
- // from 'tableViewHeightForRowAtIndexPath' method too (in iOS 7.1) and we don't want to arrange the fake cell.
91
139
  var width = layout.getMeasureSpecSize(owner.widthMeasureSpec);
92
140
  var rowHeight = owner._effectiveRowHeight;
93
141
  var cellHeight = rowHeight > 0 ? rowHeight : owner.getHeight(indexPath.row);
@@ -103,7 +151,7 @@ var DataSource = /** @class */ (function (_super) {
103
151
  DataSource.ObjCProtocols = [UITableViewDataSource];
104
152
  return DataSource;
105
153
  }(NSObject));
106
- var UITableViewDelegateImpl = /** @class */ (function (_super) {
154
+ var UITableViewDelegateImpl = (function (_super) {
107
155
  __extends(UITableViewDelegateImpl, _super);
108
156
  function UITableViewDelegateImpl() {
109
157
  return _super !== null && _super.apply(this, arguments) || this;
@@ -145,7 +193,6 @@ var UITableViewDelegateImpl = /** @class */ (function (_super) {
145
193
  }
146
194
  var height = owner.getHeight(indexPath.row);
147
195
  if (height === undefined) {
148
- // in iOS8+ after call to scrollToRowAtIndexPath:atScrollPosition:animated: this method is called before tableViewCellForRowAtIndexPath so we need fake cell to measure its content.
149
196
  var template = owner._getItemTemplate(indexPath.row);
150
197
  var cell = this._measureCellMap.get(template.key);
151
198
  if (!cell) {
@@ -156,10 +203,49 @@ var UITableViewDelegateImpl = /** @class */ (function (_super) {
156
203
  }
157
204
  return layout.toDeviceIndependentPixels(height);
158
205
  };
206
+ UITableViewDelegateImpl.prototype.tableViewViewForHeaderInSection = function (tableView, section) {
207
+ var _a;
208
+ var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
209
+ if (!owner || !owner.stickyHeader || !owner.stickyHeaderTemplate) {
210
+ if (Trace.isEnabled()) {
211
+ Trace.write("ListView: No sticky header (stickyHeader: ".concat(owner === null || owner === void 0 ? void 0 : owner.stickyHeader, ", hasTemplate: ").concat(!!(owner === null || owner === void 0 ? void 0 : owner.stickyHeaderTemplate), ")"), Trace.categories.Debug);
212
+ }
213
+ return null;
214
+ }
215
+ if (Trace.isEnabled()) {
216
+ Trace.write("ListView: Creating sticky header", Trace.categories.Debug);
217
+ }
218
+ var headerReuseIdentifier = "stickyHeader";
219
+ var headerCell = tableView.dequeueReusableHeaderFooterViewWithIdentifier(headerReuseIdentifier);
220
+ if (!headerCell) {
221
+ headerCell = ListViewHeaderCell.alloc().initWithReuseIdentifier(headerReuseIdentifier);
222
+ headerCell.backgroundColor = UIColor.clearColor;
223
+ }
224
+ owner._prepareHeader(headerCell, section);
225
+ return headerCell;
226
+ };
227
+ UITableViewDelegateImpl.prototype.tableViewHeightForHeaderInSection = function (tableView, section) {
228
+ var _a;
229
+ var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
230
+ if (!owner || !owner.stickyHeader) {
231
+ return 0;
232
+ }
233
+ var height;
234
+ if (owner.stickyHeaderHeight === "auto") {
235
+ height = 44;
236
+ }
237
+ else {
238
+ height = layout.toDeviceIndependentPixels(Length.toDevicePixels(owner.stickyHeaderHeight, 44));
239
+ }
240
+ if (Trace.isEnabled()) {
241
+ Trace.write("ListView: Sticky header height: ".concat(height), Trace.categories.Debug);
242
+ }
243
+ return height;
244
+ };
159
245
  UITableViewDelegateImpl.ObjCProtocols = [UITableViewDelegate];
160
246
  return UITableViewDelegateImpl;
161
247
  }(NSObject));
162
- var UITableViewRowHeightDelegateImpl = /** @class */ (function (_super) {
248
+ var UITableViewRowHeightDelegateImpl = (function (_super) {
163
249
  __extends(UITableViewRowHeightDelegateImpl, _super);
164
250
  function UITableViewRowHeightDelegateImpl() {
165
251
  return _super !== null && _super.apply(this, arguments) || this;
@@ -200,14 +286,83 @@ var UITableViewRowHeightDelegateImpl = /** @class */ (function (_super) {
200
286
  }
201
287
  return layout.toDeviceIndependentPixels(owner._effectiveRowHeight);
202
288
  };
289
+ UITableViewRowHeightDelegateImpl.prototype.tableViewViewForHeaderInSection = function (tableView, section) {
290
+ var _a;
291
+ var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
292
+ if (!owner || !owner.stickyHeader || !owner.stickyHeaderTemplate) {
293
+ if (Trace.isEnabled()) {
294
+ Trace.write("ListView: No sticky header (stickyHeader: ".concat(owner === null || owner === void 0 ? void 0 : owner.stickyHeader, ", hasTemplate: ").concat(!!(owner === null || owner === void 0 ? void 0 : owner.stickyHeaderTemplate), ")"), Trace.categories.Debug);
295
+ }
296
+ return null;
297
+ }
298
+ if (Trace.isEnabled()) {
299
+ Trace.write("ListView: Creating sticky header", Trace.categories.Debug);
300
+ }
301
+ var headerReuseIdentifier = "stickyHeader";
302
+ var headerCell = tableView.dequeueReusableHeaderFooterViewWithIdentifier(headerReuseIdentifier);
303
+ if (!headerCell) {
304
+ headerCell = ListViewHeaderCell.alloc().initWithReuseIdentifier(headerReuseIdentifier);
305
+ headerCell.backgroundColor = UIColor.clearColor;
306
+ }
307
+ owner._prepareHeader(headerCell, section);
308
+ return headerCell;
309
+ };
310
+ UITableViewRowHeightDelegateImpl.prototype.tableViewHeightForHeaderInSection = function (tableView, section) {
311
+ var _a;
312
+ var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.deref();
313
+ if (!owner || !owner.stickyHeader) {
314
+ return 0;
315
+ }
316
+ var height;
317
+ if (owner.stickyHeaderHeight === "auto") {
318
+ height = 44;
319
+ }
320
+ else {
321
+ height = layout.toDeviceIndependentPixels(Length.toDevicePixels(owner.stickyHeaderHeight, 44));
322
+ }
323
+ if (Trace.isEnabled()) {
324
+ Trace.write("ListView: Sticky header height: ".concat(height), Trace.categories.Debug);
325
+ }
326
+ return height;
327
+ };
203
328
  UITableViewRowHeightDelegateImpl.ObjCProtocols = [UITableViewDelegate];
204
329
  return UITableViewRowHeightDelegateImpl;
205
330
  }(NSObject));
331
+ var UISearchResultsUpdatingImpl = (function (_super) {
332
+ __extends(UISearchResultsUpdatingImpl, _super);
333
+ function UISearchResultsUpdatingImpl() {
334
+ return _super !== null && _super.apply(this, arguments) || this;
335
+ }
336
+ UISearchResultsUpdatingImpl.initWithOwner = function (owner) {
337
+ var handler = UISearchResultsUpdatingImpl.new();
338
+ handler._owner = owner;
339
+ return handler;
340
+ };
341
+ UISearchResultsUpdatingImpl.prototype.updateSearchResultsForSearchController = function (searchController) {
342
+ var owner = this._owner ? this._owner.get() : null;
343
+ if (!owner) {
344
+ return;
345
+ }
346
+ var searchText = searchController.searchBar.text || "";
347
+ owner._isSearchActive = searchController.active;
348
+ var eventData = {
349
+ eventName: ListViewBase.searchChangeEvent,
350
+ object: owner,
351
+ text: searchText,
352
+ ios: searchController,
353
+ };
354
+ owner.notify(eventData);
355
+ };
356
+ UISearchResultsUpdatingImpl.ObjCProtocols = [UISearchResultsUpdating];
357
+ return UISearchResultsUpdatingImpl;
358
+ }(NSObject));
206
359
  export class ListView extends ListViewBase {
207
360
  constructor() {
208
361
  super();
362
+ this._isSearchActive = false;
209
363
  this.widthMeasureSpec = 0;
210
364
  this._map = new Map();
365
+ this._headerMap = new Map();
211
366
  this._heights = new Array();
212
367
  }
213
368
  createNativeView() {
@@ -217,17 +372,125 @@ export class ListView extends ListViewBase {
217
372
  super.initNativeView();
218
373
  const nativeView = this.nativeViewProtected;
219
374
  nativeView.registerClassForCellReuseIdentifier(ListViewCell.class(), this._defaultTemplate.key);
375
+ nativeView.registerClassForHeaderFooterViewReuseIdentifier(ListViewHeaderCell.class(), 'stickyHeader');
220
376
  nativeView.estimatedRowHeight = DEFAULT_HEIGHT;
221
377
  nativeView.rowHeight = UITableViewAutomaticDimension;
222
378
  nativeView.dataSource = this._dataSource = DataSource.initWithOwner(new WeakRef(this));
223
379
  this._delegate = UITableViewDelegateImpl.initWithOwner(new WeakRef(this));
380
+ // Control section header top padding (iOS 15+)
381
+ if (nativeView.respondsToSelector('setSectionHeaderTopPadding:')) {
382
+ if (!this.stickyHeaderTopPadding) {
383
+ nativeView.sectionHeaderTopPadding = 0;
384
+ }
385
+ // When stickyHeaderTopPadding is true, don't set the property to use iOS default
386
+ }
224
387
  this._setNativeClipToBounds();
225
388
  }
226
389
  disposeNativeView() {
390
+ this._cleanupSearchController();
227
391
  this._delegate = null;
228
392
  this._dataSource = null;
229
393
  super.disposeNativeView();
230
394
  }
395
+ _setupSearchController() {
396
+ if (!this.showSearch || this._searchController) {
397
+ return; // Already setup or not needed
398
+ }
399
+ // 1. Create UISearchController with nil (show results in this table)
400
+ this._searchController = UISearchController.alloc().initWithSearchResultsController(null);
401
+ this._searchDelegate = UISearchResultsUpdatingImpl.initWithOwner(new WeakRef(this));
402
+ // 2. Tell it who will update results
403
+ this._searchController.searchResultsUpdater = this._searchDelegate;
404
+ // 3. Critical: Don't dim or obscure the table, and prevent extra content
405
+ this._searchController.obscuresBackgroundDuringPresentation = false;
406
+ this._searchController.dimsBackgroundDuringPresentation = false;
407
+ this._searchController.hidesNavigationBarDuringPresentation = false;
408
+ // 4. Placeholder text and styling
409
+ this._searchController.searchBar.placeholder = 'Search';
410
+ this._searchController.searchBar.searchBarStyle = 2 /* UISearchBarStyle.Minimal */;
411
+ // 5. CRITICAL: Proper presentation context setup
412
+ const viewController = this._getViewController();
413
+ if (viewController) {
414
+ viewController.definesPresentationContext = true;
415
+ viewController.providesPresentationContextTransitionStyle = true;
416
+ // 6a. If we're in a UINavigationController (iOS 11+)...
417
+ if (SDK_VERSION >= 11.0 && viewController.navigationItem) {
418
+ viewController.navigationItem.searchController = this._searchController;
419
+ // Set auto-hide behavior based on searchAutoHide property
420
+ viewController.navigationItem.hidesSearchBarWhenScrolling = this.searchAutoHide;
421
+ // Optional: Enable large titles for better auto-hide effect when searchAutoHide is true
422
+ // if (this.searchAutoHide && viewController.navigationController && viewController.navigationController.navigationBar) {
423
+ // // Only set large titles if not already configured
424
+ // if (!viewController.navigationController.navigationBar.prefersLargeTitles) {
425
+ // viewController.navigationController.navigationBar.prefersLargeTitles = true;
426
+ // }
427
+ // // Set large title display mode for this specific view controller
428
+ // if (viewController.navigationItem.largeTitleDisplayMode === UINavigationItemLargeTitleDisplayMode.Automatic) {
429
+ // viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always;
430
+ // }
431
+ // }
432
+ }
433
+ else {
434
+ // 6b. Fallback: put it at the top of our table
435
+ this.nativeViewProtected.tableHeaderView = this._searchController.searchBar;
436
+ }
437
+ }
438
+ else {
439
+ // Fallback: no view controller found, use table header
440
+ this.nativeViewProtected.tableHeaderView = this._searchController.searchBar;
441
+ }
442
+ // 7. Ensure search bar is properly sized and prevent content inset issues
443
+ this._searchController.searchBar.sizeToFit();
444
+ // 8. Disable automatic content inset adjustment that can cause spacing issues
445
+ if (this.nativeViewProtected.respondsToSelector('setContentInsetAdjustmentBehavior:')) {
446
+ // iOS 11+ - prevent automatic content inset adjustments
447
+ this.nativeViewProtected.contentInsetAdjustmentBehavior = 2 /* UIScrollViewContentInsetAdjustmentBehavior.Never */;
448
+ }
449
+ else {
450
+ // iOS 10 and below - disable automatic content inset
451
+ this.nativeViewProtected.automaticallyAdjustsScrollIndicatorInsets = false;
452
+ }
453
+ if (Trace.isEnabled()) {
454
+ Trace.write(`ListView: UISearchController setup complete with searchAutoHide: ${this.searchAutoHide}`, Trace.categories.Debug);
455
+ }
456
+ }
457
+ _cleanupSearchController() {
458
+ if (!this._searchController) {
459
+ return;
460
+ }
461
+ // Remove search controller from navigation item or table header
462
+ const viewController = this._getViewController();
463
+ if (viewController && viewController.navigationItem && viewController.navigationItem.searchController === this._searchController) {
464
+ viewController.navigationItem.searchController = null;
465
+ }
466
+ else if (this.nativeViewProtected.tableHeaderView === this._searchController.searchBar) {
467
+ this.nativeViewProtected.tableHeaderView = null;
468
+ }
469
+ // Reset content inset adjustment behavior
470
+ if (this.nativeViewProtected.respondsToSelector('setContentInsetAdjustmentBehavior:')) {
471
+ // iOS 11+ - restore automatic content inset adjustments
472
+ this.nativeViewProtected.contentInsetAdjustmentBehavior = 0 /* UIScrollViewContentInsetAdjustmentBehavior.Automatic */;
473
+ }
474
+ else {
475
+ // iOS 10 and below - restore automatic content inset
476
+ this.nativeViewProtected.automaticallyAdjustsScrollIndicatorInsets = true;
477
+ }
478
+ // Cleanup references
479
+ this._searchController.searchResultsUpdater = null;
480
+ this._searchController = null;
481
+ this._searchDelegate = null;
482
+ }
483
+ _getViewController() {
484
+ // Helper to get the current view controller
485
+ let parent = this.parent;
486
+ while (parent) {
487
+ if (parent.viewController) {
488
+ return parent.viewController;
489
+ }
490
+ parent = parent.parent;
491
+ }
492
+ return null;
493
+ }
231
494
  _setNativeClipToBounds() {
232
495
  // Always set clipsToBounds for list-view
233
496
  const view = this.nativeViewProtected;
@@ -241,18 +504,25 @@ export class ListView extends ListViewBase {
241
504
  this.refresh();
242
505
  }
243
506
  this.nativeViewProtected.delegate = this._delegate;
507
+ // Setup search controller if enabled
508
+ if (this.showSearch) {
509
+ this._setupSearchController();
510
+ }
244
511
  }
245
512
  // @ts-ignore
246
513
  get ios() {
247
514
  return this.nativeViewProtected;
248
515
  }
249
516
  get _childrenCount() {
250
- return this._map.size;
517
+ return this._map.size + this._headerMap.size;
251
518
  }
252
519
  eachChildView(callback) {
253
520
  this._map.forEach((view, key) => {
254
521
  callback(view);
255
522
  });
523
+ this._headerMap.forEach((view, key) => {
524
+ callback(view);
525
+ });
256
526
  }
257
527
  scrollToIndex(index) {
258
528
  this._scrollToIndex(index, false);
@@ -286,6 +556,11 @@ export class ListView extends ListViewBase {
286
556
  view.bindingContext = null;
287
557
  }
288
558
  });
559
+ this._headerMap.forEach((view, nativeView, map) => {
560
+ if (!(view.bindingContext instanceof Observable)) {
561
+ view.bindingContext = null;
562
+ }
563
+ });
289
564
  if (this.isLoaded) {
290
565
  this.nativeViewProtected.reloadData();
291
566
  this.requestLayout();
@@ -324,8 +599,8 @@ export class ListView extends ListViewBase {
324
599
  super._onRowHeightPropertyChanged(oldValue, newValue);
325
600
  }
326
601
  requestLayout() {
327
- // When preparing cell don't call super - no need to invalidate our measure when cell desiredSize is changed.
328
- if (!this._preparingCell) {
602
+ // When preparing cell or header don't call super - no need to invalidate our measure when cell/header desiredSize is changed.
603
+ if (!this._preparingCell && !this._preparingHeader) {
329
604
  super.requestLayout();
330
605
  }
331
606
  }
@@ -343,6 +618,9 @@ export class ListView extends ListViewBase {
343
618
  this._map.forEach((childView, listViewCell) => {
344
619
  View.measureChild(this, childView, childView._currentWidthMeasureSpec, childView._currentHeightMeasureSpec);
345
620
  });
621
+ this._headerMap.forEach((childView, listViewHeaderCell) => {
622
+ View.measureChild(this, childView, childView._currentWidthMeasureSpec, childView._currentHeightMeasureSpec);
623
+ });
346
624
  }
347
625
  onLayout(left, top, right, bottom) {
348
626
  super.onLayout(left, top, right, bottom);
@@ -355,6 +633,12 @@ export class ListView extends ListViewBase {
355
633
  View.layoutChild(this, childView, 0, 0, width, cellHeight);
356
634
  }
357
635
  });
636
+ this._headerMap.forEach((childView, listViewHeaderCell) => {
637
+ const headerHeight = this.stickyHeaderHeight === 'auto' ? 44 : Length.toDevicePixels(this.stickyHeaderHeight, 44);
638
+ const width = layout.getMeasureSpecSize(this.widthMeasureSpec);
639
+ childView.iosOverflowSafeAreaEnabled = false;
640
+ View.layoutChild(this, childView, 0, 0, width, headerHeight);
641
+ });
358
642
  }
359
643
  _layoutCell(cellView, indexPath) {
360
644
  if (cellView) {
@@ -373,10 +657,21 @@ export class ListView extends ListViewBase {
373
657
  this._preparingCell = true;
374
658
  let view = cell.view;
375
659
  if (!view) {
376
- view = this._getItemTemplate(indexPath.row).createView();
660
+ if (this.sectioned) {
661
+ // For sectioned data, we need to calculate the absolute index for template selection
662
+ let absoluteIndex = 0;
663
+ for (let i = 0; i < indexPath.section; i++) {
664
+ absoluteIndex += this._getItemsInSection(i).length;
665
+ }
666
+ absoluteIndex += indexPath.row;
667
+ view = this._getItemTemplate(absoluteIndex).createView();
668
+ }
669
+ else {
670
+ view = this._getItemTemplate(indexPath.row).createView();
671
+ }
377
672
  }
378
673
  const args = notifyForItemAtIndex(this, cell, view, ITEMLOADING, indexPath);
379
- view = args.view || this._getDefaultItemContent(indexPath.row);
674
+ view = args.view || this._getDefaultItemContent(this.sectioned ? indexPath.row : indexPath.row);
380
675
  // Proxy containers should not get treated as layouts.
381
676
  // Wrap them in a real layout as well.
382
677
  if (view instanceof ProxyViewContainer) {
@@ -394,8 +689,15 @@ export class ListView extends ListViewBase {
394
689
  this._removeContainer(cell);
395
690
  cell.owner = new WeakRef(view);
396
691
  }
397
- this._prepareItem(view, indexPath.row);
398
- view._listViewItemIndex = indexPath.row;
692
+ if (this.sectioned) {
693
+ this._prepareItemInSection(view, indexPath.section, indexPath.row);
694
+ view._listViewItemIndex = indexPath.row; // Keep row index for compatibility
695
+ view._listViewSectionIndex = indexPath.section;
696
+ }
697
+ else {
698
+ this._prepareItem(view, indexPath.row);
699
+ view._listViewItemIndex = indexPath.row;
700
+ }
399
701
  this._map.set(cell, view);
400
702
  // We expect that views returned from itemLoading are new (e.g. not reused).
401
703
  if (view && !view.parent) {
@@ -423,6 +725,151 @@ export class ListView extends ListViewBase {
423
725
  this._preparingCell = preparing;
424
726
  this._map.delete(cell);
425
727
  }
728
+ _prepareHeader(headerCell, section) {
729
+ let headerHeight;
730
+ try {
731
+ this._preparingHeader = true;
732
+ let view = headerCell.view;
733
+ if (!view) {
734
+ view = this._getHeaderTemplate();
735
+ if (!view) {
736
+ if (Trace.isEnabled()) {
737
+ Trace.write(`ListView: Failed to create header view for section ${section}`, Trace.categories.Debug);
738
+ }
739
+ // Create a fallback view
740
+ const lbl = new Label();
741
+ lbl.text = `Section ${section}`;
742
+ view = lbl;
743
+ }
744
+ }
745
+ // Handle header cell reuse
746
+ if (!headerCell.view) {
747
+ headerCell.owner = new WeakRef(view);
748
+ }
749
+ else if (headerCell.view !== view) {
750
+ // Remove old view and set new one
751
+ headerCell.view.nativeViewProtected?.removeFromSuperview();
752
+ this._removeHeaderContainer(headerCell);
753
+ headerCell.owner = new WeakRef(view);
754
+ }
755
+ // Clear existing binding context and set new one
756
+ if (view.bindingContext) {
757
+ view.bindingContext = null;
758
+ }
759
+ if (this.sectioned) {
760
+ const sectionData = this._getSectionData(section);
761
+ if (sectionData) {
762
+ view.bindingContext = sectionData;
763
+ }
764
+ else {
765
+ // Fallback if section data is missing
766
+ view.bindingContext = { title: `Section ${section}`, section: section };
767
+ }
768
+ }
769
+ else {
770
+ view.bindingContext = this.bindingContext;
771
+ }
772
+ // Force immediate binding context evaluation
773
+ if (view && typeof view._onBindingContextChanged === 'function') {
774
+ view._onBindingContextChanged(null, view.bindingContext);
775
+ // Also trigger for child views
776
+ // @ts-ignore
777
+ if (view._childrenCount) {
778
+ view.eachChildView((child) => {
779
+ if (typeof child._onBindingContextChanged === 'function') {
780
+ child._onBindingContextChanged(null, view.bindingContext);
781
+ }
782
+ return true;
783
+ });
784
+ }
785
+ }
786
+ this._headerMap.set(headerCell, view);
787
+ // Add new header view to the cell
788
+ if (view && !view.parent) {
789
+ this._addView(view);
790
+ headerCell.contentView.addSubview(view.nativeViewProtected);
791
+ }
792
+ // Request layout and measure/layout the header
793
+ if (view && view.bindingContext) {
794
+ view.requestLayout();
795
+ }
796
+ headerHeight = this._layoutHeader(view);
797
+ }
798
+ finally {
799
+ this._preparingHeader = false;
800
+ }
801
+ return headerHeight;
802
+ }
803
+ _layoutHeader(headerView) {
804
+ if (headerView) {
805
+ const headerHeight = this.stickyHeaderHeight === 'auto' ? 44 : Length.toDevicePixels(this.stickyHeaderHeight, 44);
806
+ const heightMeasureSpec = layout.makeMeasureSpec(headerHeight, layout.EXACTLY);
807
+ const measuredSize = View.measureChild(this, headerView, this.widthMeasureSpec, heightMeasureSpec);
808
+ // Layout the header with the measured size
809
+ View.layoutChild(this, headerView, 0, 0, measuredSize.measuredWidth, measuredSize.measuredHeight);
810
+ return measuredSize.measuredHeight;
811
+ }
812
+ return 44;
813
+ }
814
+ _getHeaderTemplate() {
815
+ if (this.stickyHeaderTemplate) {
816
+ if (__UI_USE_EXTERNAL_RENDERER__) {
817
+ if (isFunction(this.stickyHeaderTemplate)) {
818
+ return this.stickyHeaderTemplate();
819
+ }
820
+ }
821
+ else {
822
+ if (typeof this.stickyHeaderTemplate === 'string') {
823
+ try {
824
+ const parsed = Builder.parse(this.stickyHeaderTemplate, this);
825
+ if (!parsed) {
826
+ // Create a simple fallback
827
+ const fallbackLabel = new Label();
828
+ fallbackLabel.text = 'Parse Failed';
829
+ return fallbackLabel;
830
+ }
831
+ return parsed;
832
+ }
833
+ catch (error) {
834
+ if (Trace.isEnabled()) {
835
+ Trace.write(`ListView: Template parsing error: ${error}`, Trace.categories.Debug);
836
+ }
837
+ // Create a simple fallback
838
+ const errorLabel = new Label();
839
+ errorLabel.text = 'Template Error';
840
+ return errorLabel;
841
+ }
842
+ }
843
+ else {
844
+ const view = this.stickyHeaderTemplate();
845
+ if (Trace.isEnabled()) {
846
+ Trace.write(`ListView: Created header view from template function: ${!!view} (type: ${view?.constructor?.name})`, Trace.categories.Debug);
847
+ }
848
+ return view;
849
+ }
850
+ }
851
+ }
852
+ if (Trace.isEnabled()) {
853
+ Trace.write(`ListView: No sticky header template, creating default`, Trace.categories.Debug);
854
+ }
855
+ // Return a default header if no template is provided
856
+ const lbl = new Label();
857
+ lbl.text = 'Default Header';
858
+ return lbl;
859
+ }
860
+ _removeHeaderContainer(headerCell) {
861
+ const view = headerCell.view;
862
+ // This is to clear the StackLayout that is used to wrap ProxyViewContainer instances.
863
+ if (!(view.parent instanceof ListView)) {
864
+ this._removeView(view.parent);
865
+ }
866
+ // No need to request layout when we are removing headers.
867
+ const preparing = this._preparingHeader;
868
+ this._preparingHeader = true;
869
+ view.parent._removeView(view);
870
+ this._preparingHeader = preparing;
871
+ this._headerMap.delete(headerCell);
872
+ }
426
873
  [separatorColorProperty.getDefault]() {
427
874
  return this.nativeViewProtected.separatorColor;
428
875
  }
@@ -450,6 +897,95 @@ export class ListView extends ListViewBase {
450
897
  const estimatedHeight = layout.toDeviceIndependentPixels(Length.toDevicePixels(value, 0));
451
898
  nativeView.estimatedRowHeight = estimatedHeight < 0 ? DEFAULT_HEIGHT : estimatedHeight;
452
899
  }
900
+ [stickyHeaderProperty.getDefault]() {
901
+ return false;
902
+ }
903
+ [stickyHeaderProperty.setNative](value) {
904
+ if (Trace.isEnabled()) {
905
+ Trace.write(`ListView: stickyHeader set to ${value}`, Trace.categories.Debug);
906
+ }
907
+ // Immediately refresh to apply changes
908
+ if (this.isLoaded) {
909
+ this.refresh();
910
+ }
911
+ }
912
+ [stickyHeaderTemplateProperty.getDefault]() {
913
+ return null;
914
+ }
915
+ [stickyHeaderTemplateProperty.setNative](value) {
916
+ if (Trace.isEnabled()) {
917
+ Trace.write(`ListView: stickyHeaderTemplate set: ${typeof value} ${value ? '(has value)' : '(null)'}`, Trace.categories.Debug);
918
+ }
919
+ // Clear any cached template
920
+ this._headerTemplateCache = null;
921
+ // Immediately refresh to apply changes
922
+ if (this.isLoaded) {
923
+ this.refresh();
924
+ }
925
+ }
926
+ [stickyHeaderHeightProperty.getDefault]() {
927
+ return 'auto';
928
+ }
929
+ [stickyHeaderHeightProperty.setNative](value) {
930
+ if (Trace.isEnabled()) {
931
+ Trace.write(`ListView: stickyHeaderHeight set to ${value}`, Trace.categories.Debug);
932
+ }
933
+ // Immediately refresh to apply changes
934
+ if (this.isLoaded) {
935
+ this.refresh();
936
+ }
937
+ }
938
+ [sectionedProperty.getDefault]() {
939
+ return false;
940
+ }
941
+ [sectionedProperty.setNative](value) {
942
+ if (Trace.isEnabled()) {
943
+ Trace.write(`ListView: sectioned set to ${value}`, Trace.categories.Debug);
944
+ }
945
+ // Immediately refresh to apply changes
946
+ if (this.isLoaded) {
947
+ this.refresh();
948
+ }
949
+ }
950
+ [showSearchProperty.getDefault]() {
951
+ return false;
952
+ }
953
+ [showSearchProperty.setNative](value) {
954
+ if (Trace.isEnabled()) {
955
+ Trace.write(`ListView: showSearch set to ${value}`, Trace.categories.Debug);
956
+ }
957
+ if (value) {
958
+ this._setupSearchController();
959
+ }
960
+ else {
961
+ this._cleanupSearchController();
962
+ }
963
+ }
964
+ [searchAutoHideProperty.getDefault]() {
965
+ return false;
966
+ }
967
+ [searchAutoHideProperty.setNative](value) {
968
+ if (Trace.isEnabled()) {
969
+ Trace.write(`ListView: searchAutoHide set to ${value}`, Trace.categories.Debug);
970
+ }
971
+ // If search is already enabled, update the existing search controller
972
+ if (this.showSearch && this._searchController) {
973
+ const viewController = this._getViewController();
974
+ if (viewController && viewController.navigationItem && SDK_VERSION >= 11.0) {
975
+ viewController.navigationItem.hidesSearchBarWhenScrolling = value;
976
+ // Enable large titles for better auto-hide effect when searchAutoHide is true
977
+ // if (value && viewController.navigationController && viewController.navigationController.navigationBar) {
978
+ // if (!viewController.navigationController.navigationBar.prefersLargeTitles) {
979
+ // viewController.navigationController.navigationBar.prefersLargeTitles = true;
980
+ // }
981
+ // if (viewController.navigationItem.largeTitleDisplayMode === UINavigationItemLargeTitleDisplayMode.Automatic) {
982
+ // viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always;
983
+ // }
984
+ // }
985
+ }
986
+ }
987
+ // If search is not enabled yet, the property will be used when _setupSearchController is called
988
+ }
453
989
  }
454
990
  __decorate([
455
991
  profile,