@maccesar/titools 2.0.6 → 2.2.0

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 (132) hide show
  1. package/{AGENTS-TEMPLATE.md → AGENTS-VERCEL-RESEARCH.md} +16 -18
  2. package/README.md +250 -168
  3. package/agents/{ti-researcher.md → ti-pro.md} +10 -10
  4. package/bin/titools.js +16 -12
  5. package/lib/cleanup.js +95 -0
  6. package/lib/commands/agents.js +146 -70
  7. package/lib/commands/skills.js +349 -0
  8. package/lib/commands/uninstall.js +189 -154
  9. package/lib/commands/update.js +104 -21
  10. package/lib/config.js +26 -20
  11. package/lib/downloader.js +1 -1
  12. package/lib/installer.js +37 -97
  13. package/lib/platform.js +9 -5
  14. package/lib/prompts/checkboxCancel.js +264 -0
  15. package/lib/prompts/selectCancel.js +204 -0
  16. package/lib/symlink.js +19 -7
  17. package/lib/utils.js +21 -31
  18. package/package.json +10 -10
  19. package/skills/alloy-guides/SKILL.md +8 -30
  20. package/skills/alloy-guides/references/CLI_TASKS.md +14 -24
  21. package/skills/alloy-guides/references/CONCEPTS.md +5 -25
  22. package/skills/alloy-guides/references/CONTROLLERS.md +2 -19
  23. package/skills/alloy-guides/references/MODELS.md +40 -10
  24. package/skills/alloy-guides/references/PURGETSS.md +1 -11
  25. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +8 -14
  26. package/skills/alloy-guides/references/VIEWS_STYLES.md +14 -25
  27. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +2 -8
  28. package/skills/alloy-guides/references/VIEWS_XML.md +29 -40
  29. package/skills/alloy-guides/references/WIDGETS.md +1 -17
  30. package/skills/alloy-howtos/SKILL.md +1 -22
  31. package/skills/alloy-howtos/references/best_practices.md +0 -17
  32. package/skills/alloy-howtos/references/cli_reference.md +1 -23
  33. package/skills/alloy-howtos/references/config_files.md +86 -15
  34. package/skills/alloy-howtos/references/custom_tags.md +14 -13
  35. package/skills/alloy-howtos/references/debugging_troubleshooting.md +3 -22
  36. package/skills/alloy-howtos/references/samples.md +4 -14
  37. package/skills/purgetss/SKILL.md +11 -37
  38. package/skills/purgetss/references/EXAMPLES.md +106 -17
  39. package/skills/purgetss/references/animation-system.md +0 -67
  40. package/skills/purgetss/references/apply-directive.md +0 -18
  41. package/skills/purgetss/references/arbitrary-values.md +0 -25
  42. package/skills/purgetss/references/class-index.md +0 -46
  43. package/skills/purgetss/references/cli-commands.md +0 -41
  44. package/skills/purgetss/references/configurable-properties.md +0 -55
  45. package/skills/purgetss/references/custom-rules.md +0 -14
  46. package/skills/purgetss/references/customization-deep-dive.md +0 -49
  47. package/skills/purgetss/references/dynamic-component-creation.md +56 -37
  48. package/skills/purgetss/references/grid-layout.md +0 -32
  49. package/skills/purgetss/references/icon-fonts.md +0 -50
  50. package/skills/purgetss/references/installation-setup.md +61 -32
  51. package/skills/purgetss/references/migration-guide.md +127 -0
  52. package/skills/purgetss/references/opacity-modifier.md +0 -34
  53. package/skills/purgetss/references/performance-tips.md +261 -0
  54. package/skills/purgetss/references/platform-modifiers.md +0 -46
  55. package/skills/purgetss/references/smart-mappings.md +0 -12
  56. package/skills/purgetss/references/tikit-components.md +393 -0
  57. package/skills/purgetss/references/titanium-resets.md +1 -27
  58. package/skills/purgetss/references/ui-ux-design.md +467 -117
  59. package/skills/{alloy-expert → ti-expert}/SKILL.md +45 -54
  60. package/skills/ti-expert/references/alloy-builtins.md +387 -0
  61. package/skills/{alloy-expert → ti-expert}/references/alloy-structure.md +147 -40
  62. package/skills/ti-expert/references/anti-patterns.md +90 -0
  63. package/skills/ti-expert/references/cli-expert.md +109 -0
  64. package/skills/{alloy-expert → ti-expert}/references/code-conventions.md +182 -49
  65. package/skills/{alloy-expert → ti-expert}/references/controller-patterns.md +103 -93
  66. package/skills/{alloy-expert → ti-expert}/references/error-handling.md +12 -12
  67. package/skills/{alloy-expert → ti-expert}/references/examples.md +144 -85
  68. package/skills/{alloy-expert → ti-expert}/references/migration-patterns.md +38 -36
  69. package/skills/{alloy-expert → ti-expert}/references/patterns.md +8 -8
  70. package/skills/ti-expert/references/performance-listview.md +251 -0
  71. package/skills/{alloy-expert/references/performance-patterns.md → ti-expert/references/performance-optimization.md} +67 -283
  72. package/skills/{alloy-expert/references/security-patterns.md → ti-expert/references/security-device.md} +12 -295
  73. package/skills/ti-expert/references/security-fundamentals.md +284 -0
  74. package/skills/{alloy-expert → ti-expert}/references/state-management.md +10 -10
  75. package/skills/ti-expert/references/testing-e2e-ci.md +432 -0
  76. package/skills/ti-expert/references/testing-unit.md +433 -0
  77. package/skills/ti-expert/references/theming.md +394 -0
  78. package/skills/ti-guides/SKILL.md +1 -14
  79. package/skills/ti-guides/references/advanced-data-and-images.md +126 -10
  80. package/skills/ti-guides/references/app-distribution.md +48 -10
  81. package/skills/ti-guides/references/application-frameworks.md +9 -2
  82. package/skills/ti-guides/references/cli-reference.md +338 -82
  83. package/skills/ti-guides/references/coding-best-practices.md +14 -4
  84. package/skills/ti-guides/references/commonjs-advanced.md +103 -6
  85. package/skills/ti-guides/references/hello-world.md +5 -2
  86. package/skills/ti-guides/references/hyperloop-native-access.md +439 -46
  87. package/skills/ti-guides/references/javascript-primer.md +4 -3
  88. package/skills/ti-guides/references/resources.md +0 -1
  89. package/skills/ti-guides/references/style-and-conventions.md +57 -9
  90. package/skills/ti-guides/references/tiapp-config.md +48 -6
  91. package/skills/ti-howtos/SKILL.md +2 -27
  92. package/skills/ti-howtos/references/android-platform-deep-dives.md +41 -90
  93. package/skills/ti-howtos/references/automation-fastlane-appium.md +15 -14
  94. package/skills/ti-howtos/references/buffer-codec-streams.md +22 -22
  95. package/skills/ti-howtos/references/cross-platform-development.md +68 -37
  96. package/skills/ti-howtos/references/debugging-profiling.md +8 -53
  97. package/skills/ti-howtos/references/extending-titanium.md +12 -51
  98. package/skills/ti-howtos/references/google-maps-v2.md +30 -29
  99. package/skills/ti-howtos/references/ios-map-kit.md +19 -25
  100. package/skills/ti-howtos/references/ios-platform-deep-dives.md +95 -283
  101. package/skills/ti-howtos/references/local-data-sources.md +45 -37
  102. package/skills/ti-howtos/references/location-and-maps.md +47 -28
  103. package/skills/ti-howtos/references/media-apis.md +84 -27
  104. package/skills/ti-howtos/references/notification-services.md +40 -89
  105. package/skills/ti-howtos/references/remote-data-sources.md +21 -36
  106. package/skills/ti-howtos/references/tutorials.md +79 -39
  107. package/skills/ti-howtos/references/using-modules.md +4 -30
  108. package/skills/ti-howtos/references/web-content-integration.md +28 -45
  109. package/skills/ti-howtos/references/webpack-build-pipeline.md +54 -18
  110. package/skills/ti-ui/SKILL.md +1 -21
  111. package/skills/ti-ui/references/accessibility-deep-dive.md +71 -25
  112. package/skills/ti-ui/references/animation-and-matrices.md +0 -47
  113. package/skills/ti-ui/references/application-structures.md +0 -46
  114. package/skills/ti-ui/references/custom-fonts-styling.md +9 -57
  115. package/skills/ti-ui/references/event-handling.md +32 -40
  116. package/skills/ti-ui/references/gestures.md +0 -40
  117. package/skills/ti-ui/references/icons-and-splash-screens.md +21 -44
  118. package/skills/ti-ui/references/layouts-and-positioning.md +47 -39
  119. package/skills/ti-ui/references/listviews-and-performance.md +187 -73
  120. package/skills/ti-ui/references/orientation.md +57 -71
  121. package/skills/ti-ui/references/platform-ui-android.md +114 -48
  122. package/skills/ti-ui/references/platform-ui-ios.md +63 -38
  123. package/skills/ti-ui/references/scrolling-views.md +14 -23
  124. package/skills/ti-ui/references/tableviews.md +6 -56
  125. package/lib/commands/install.js +0 -188
  126. package/skills/alloy-expert/references/anti-patterns.md +0 -133
  127. package/skills/alloy-expert/references/testing.md +0 -872
  128. package/skills/ti-guides/references/alloy-cli-advanced.md +0 -84
  129. package/skills/ti-guides/references/alloy-data-mastery.md +0 -29
  130. package/skills/ti-guides/references/alloy-widgets-and-themes.md +0 -19
  131. /package/skills/{alloy-expert → ti-expert}/assets/ControllerAutoCleanup.js +0 -0
  132. /package/skills/{alloy-expert → ti-expert}/references/contracts.md +0 -0
@@ -1,45 +1,5 @@
1
1
  # Gestures
2
2
 
3
- ## Table of Contents
4
-
5
- - [Gestures](#gestures)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. Overview](#1-overview)
8
- - [2. Touch Events](#2-touch-events)
9
- - [Touch Lifecycle](#touch-lifecycle)
10
- - [Touch Event Properties](#touch-event-properties)
11
- - [Android Note](#android-note)
12
- - [3. Swipe Gesture](#3-swipe-gesture)
13
- - [Basic Swipe](#basic-swipe)
14
- - [Swipe Direction Detection](#swipe-direction-detection)
15
- - [Swipe vs Scroll](#swipe-vs-scroll)
16
- - [4. Pinch Gesture (iOS Only)](#4-pinch-gesture-ios-only)
17
- - [Pinch to Zoom](#pinch-to-zoom)
18
- - [5. Long Press Gesture](#5-long-press-gesture)
19
- - [Basic Long Press](#basic-long-press)
20
- - [Long Press Duration](#long-press-duration)
21
- - [Android Long Press Convention](#android-long-press-convention)
22
- - [6. Shake Gesture](#6-shake-gesture)
23
- - [Detecting Shake](#detecting-shake)
24
- - [Shake Example](#shake-example)
25
- - [Testing Shake](#testing-shake)
26
- - [7. Accelerometer as Input](#7-accelerometer-as-input)
27
- - [Basic Accelerometer](#basic-accelerometer)
28
- - [Accelerometer Properties](#accelerometer-properties)
29
- - [Using Accelerometer for Control](#using-accelerometer-for-control)
30
- - [Smoothing Accelerometer Data](#smoothing-accelerometer-data)
31
- - [8. Gesture Lifecycle Management](#8-gesture-lifecycle-management)
32
- - [Battery Considerations](#battery-considerations)
33
- - [9. Platform-Specific Considerations](#9-platform-specific-considerations)
34
- - [iOS](#ios)
35
- - [Android](#android)
36
- - [10. Best Practices](#10-best-practices)
37
- - [11. Combining Gestures](#11-combining-gestures)
38
- - [Multiple Gesture Types](#multiple-gesture-types)
39
- - [Preventing Gesture Conflicts](#preventing-gesture-conflicts)
40
-
41
- ---
42
-
43
3
  ## 1. Overview
44
4
 
45
5
  Titanium supports various gestures beyond simple taps:
@@ -1,47 +1,5 @@
1
1
  # Icons and Splash Screens
2
2
 
3
- ## Table of Contents
4
-
5
- - [Icons and Splash Screens](#icons-and-splash-screens)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. Overview](#1-overview)
8
- - [2. Asset Locations](#2-asset-locations)
9
- - [3. DefaultIcon.png (Recommended)](#3-defaulticonpng-recommended)
10
- - [4. iOS Icons](#4-ios-icons)
11
- - [App Icons](#app-icons)
12
- - [Spotlight \& Settings Icons](#spotlight--settings-icons)
13
- - [iOS Splash Screens](#ios-splash-screens)
14
- - [iTunes Artwork (Ad-Hoc builds)](#itunes-artwork-ad-hoc-builds)
15
- - [iTunes Connect Requirements](#itunes-connect-requirements)
16
- - [5. Android Icons](#5-android-icons)
17
- - [Launcher Icons](#launcher-icons)
18
- - [Action Bar Icons](#action-bar-icons)
19
- - [Notification Icons](#notification-icons)
20
- - [Google Play Requirements](#google-play-requirements)
21
- - [6. Android Splash Screens](#6-android-splash-screens)
22
- - [Android 12+ (SDK 12.0.0+)](#android-12-sdk-1200)
23
- - [Android \< 12 (Legacy)](#android--12-legacy)
24
- - [Nine-Patch Images (Recommended)](#nine-patch-images-recommended)
25
- - [Density-Specific Splash Screens](#density-specific-splash-screens)
26
- - [Custom Theme Splash Screen](#custom-theme-splash-screen)
27
- - [7. Localized Splash Screens](#7-localized-splash-screens)
28
- - [Android Localization](#android-localization)
29
- - [iOS Localization](#ios-localization)
30
- - [8. Adaptive Icons (Android 8.0+)](#8-adaptive-icons-android-80)
31
- - [9. Common Issues](#9-common-issues)
32
- - [Build Fails - Missing Icons](#build-fails---missing-icons)
33
- - [Android Splash Stretched/Distorted](#android-splash-stretcheddistorted)
34
- - [iOS Icons Not Updating](#ios-icons-not-updating)
35
- - [Android 12 Splash Not Showing Custom Image](#android-12-splash-not-showing-custom-image)
36
- - [11. iOS Launch Files (Storyboards)](#11-ios-launch-files-storyboards)
37
- - [Enabling Launch Storyboards](#enabling-launch-storyboards)
38
- - [Customizing Background Color](#customizing-background-color)
39
- - [Using Images in Storyboards](#using-images-in-storyboards)
40
- - [Launch File Cache](#launch-file-cache)
41
- - [Best Practices](#best-practices)
42
-
43
- ---
44
-
45
3
  ## 1. Overview
46
4
 
47
5
  App icons and splash screens are required for app store submissions and provide visual branding during app launch.
@@ -93,6 +51,8 @@ Place a single `DefaultIcon.png` (1024x1024px) in project root. Titanium auto-ge
93
51
  | Universal retina | Settings | 58x58 | `appicon-Small@2x.png` |
94
52
  | iPhone 6 Plus+ | Settings | 87x87 | `appicon-Small@3x.png` |
95
53
 
54
+ **App Thinning note:** Application icons and launch images are added to the Asset Catalog to support App Thinning. Due to this change, you cannot reference launch image assets from the filesystem (e.g., you cannot set `backgroundImage` to a launch image file).
55
+
96
56
  ### iOS Splash Screens
97
57
 
98
58
  | Device | Dimensions | Filename |
@@ -149,7 +109,9 @@ Place a single `DefaultIcon.png` (1024x1024px) in project root. Titanium auto-ge
149
109
  | hdpi | 240 | 72x72 | `platform/android/res/drawable-hdpi/appicon.png` |
150
110
  | xhdpi | 320 | 96x96 | `platform/android/res/drawable-xhdpi/appicon.png` |
151
111
  | xxhdpi | 480 | 144x144 | `platform/android/res/drawable-xxhdpi/appicon.png` |
152
- | xxxhdpi | 640 | 192x192 | `platform/android/res/drawable-xxxhdpi/appicon.png` |
112
+ | xxxhdpi | 640 | 512x512 | `platform/android/res/drawable-xxxhdpi/appicon.png` |
113
+
114
+ The filename must match the `icon` element in your tiapp.xml file. By default, newly created projects use `Resources/android/appicon.png`.
153
115
 
154
116
  ### Action Bar Icons
155
117
 
@@ -162,6 +124,17 @@ Place a single `DefaultIcon.png` (1024x1024px) in project root. Titanium auto-ge
162
124
  | xxhdpi | 72x72 | `Resources/android/images/res-xxhdpi/` | `app/assets/android/images/res-xxhdpi/` |
163
125
  | xxxhdpi | 144x144 | `Resources/android/images/res-xxxhdpi/` | `app/assets/android/images/res-xxxhdpi/` |
164
126
 
127
+ ### Small and Contextual Icons
128
+
129
+ Used for notification status bar icons and other small UI elements:
130
+
131
+ | Density | Dimensions |
132
+ | ------- | ---------- |
133
+ | ldpi | 12x12 |
134
+ | mdpi | 16x16 |
135
+ | hdpi | 24x24 |
136
+ | xhdpi | 32x32 |
137
+
165
138
  ### Notification Icons
166
139
 
167
140
  **Important:** Must be white-on-transparent background only.
@@ -222,7 +195,9 @@ Android 12 uses app icon as splash screen automatically. Use **Adaptive Icons**
222
195
 
223
196
  ### Android < 12 (Legacy)
224
197
 
225
- Use `default.png` or nine-patch images.
198
+ Use `default.png` or nine-patch images. Android uses `default.png` (lowercase 'd') for the splash screen filename. This is different from iOS which uses uppercase `Default.png`.
199
+
200
+ **Warning:** Do not use `<supports-screens/>` with `android:anyDensity` set to false, as this can cause scaling issues with splash screens.
226
201
 
227
202
  #### Nine-Patch Images (Recommended)
228
203
 
@@ -345,6 +320,8 @@ platform/android/res/
345
320
 
346
321
  ### Build Fails - Missing Icons
347
322
 
323
+ If any app icon files are missing, the build will fail. If launch image files (prefixed with `Default`) are missing, the build will NOT fail. If you have a `DefaultIcon.png` in the project root, the Titanium SDK will auto-generate any missing iTunesArtwork files.
324
+
348
325
  **Solution:** Add `DefaultIcon.png` (1024x1024) to project root for auto-generation.
349
326
 
350
327
  ### Android Splash Stretched/Distorted
@@ -39,45 +39,6 @@ if (OS_IOS) {
39
39
  - Android: `actionBar` config, any `Ti.Android.*` constant
40
40
  :::
41
41
 
42
- ## Table of Contents
43
-
44
- - [Layouts, Positioning, and View Hierarchy](#layouts-positioning-and-view-hierarchy)
45
- - [🚨 CRITICAL: Platform-Specific Properties Require Modifiers](#-critical-platform-specific-properties-require-modifiers)
46
- - [Table of Contents](#table-of-contents)
47
- - [1. Units of Measurement](#1-units-of-measurement)
48
- - [Available Units](#available-units)
49
- - [Density-Independent Pixels (dp)](#density-independent-pixels-dp)
50
- - [Best Practice](#best-practice)
51
- - [2. Positioning Properties](#2-positioning-properties)
52
- - [Edge-Based Positioning](#edge-based-positioning)
53
- - [Center Positioning](#center-positioning)
54
- - [Dynamic Sizing](#dynamic-sizing)
55
- - [3. Layout Modes](#3-layout-modes)
56
- - [Composite (Default)](#composite-default)
57
- - [Vertical Layout](#vertical-layout)
58
- - [Horizontal Layout](#horizontal-layout)
59
- - [4. Auto-Size Behaviors](#4-auto-size-behaviors)
60
- - [Ti.UI.SIZE](#tiuisize)
61
- - [Ti.UI.FILL](#tiuifill)
62
- - [Component Defaults](#component-defaults)
63
- - [Auto-Size in Layout Modes](#auto-size-in-layout-modes)
64
- - [5. Combining Layouts](#5-combining-layouts)
65
- - [Nested Layouts](#nested-layouts)
66
- - [6. View Hierarchy and Z-Index](#6-view-hierarchy-and-z-index)
67
- - [Stacking Order](#stacking-order)
68
- - [Explicit Z-Index](#explicit-z-index)
69
- - [7. Common Layout Patterns](#7-common-layout-patterns)
70
- - [Full-Screen Overlay](#full-screen-overlay)
71
- - [Centered Content](#centered-content)
72
- - [Bottom-Aligned Content](#bottom-aligned-content)
73
- - [Percentage-Based Layout](#percentage-based-layout)
74
- - [8. Platform Considerations](#8-platform-considerations)
75
- - [Android Density-Specific Resources](#android-density-specific-resources)
76
- - [iOS Asset Catalog](#ios-asset-catalog)
77
- - [Best Practices](#best-practices)
78
-
79
- ---
80
-
81
42
  ## 1. Units of Measurement
82
43
 
83
44
  ### Available Units
@@ -87,6 +48,9 @@ if (OS_IOS) {
87
48
  | `dp` / `dip` | Density-independent pixels | **Recommended** for cross-platform |
88
49
  | `px` | Absolute pixels | Use sparingly - varies by screen density |
89
50
  | `%` | Percentage of parent size | Relative to parent's dimension |
51
+ | `mm` | Millimeters | Absolute physical unit |
52
+ | `cm` | Centimeters | Absolute physical unit |
53
+ | `in` | Inches | Absolute physical unit |
90
54
  | `system` | Platform default | iOS = dip, Android = px (unless configured) |
91
55
 
92
56
  ### Density-Independent Pixels (dp)
@@ -99,6 +63,24 @@ if (OS_IOS) {
99
63
 
100
64
  **iOS**: Effectively `1dip = 1px` on non-retina, `1dip = 2px` on retina
101
65
 
66
+ ### Default Units in tiapp.xml
67
+
68
+ You can set app-wide default units via the `ti.ui.defaultunit` property in `tiapp.xml`:
69
+
70
+ ```xml
71
+ <property name="ti.ui.defaultunit" type="string">dp</property>
72
+ ```
73
+
74
+ When set, numeric values without explicit units (e.g., `width: 100`) use this unit instead of the platform default.
75
+
76
+ ### Platform Coordinate Grid Differences
77
+
78
+ > **Important**: iOS and Android use different default coordinate systems:
79
+ > - **iOS** uses a density-independent grid (e.g., 320×480 dip for iPhone classic, 1024×768 for iPad). Values are always in dip.
80
+ > - **Android** uses a pixel-based grid by default (varies by device: HVGA 320×480px, WVGA800 480×800px, etc.).
81
+ >
82
+ > This is why setting `ti.ui.defaultunit` to `dp` is recommended for cross-platform consistency — it normalizes Android's behavior to match iOS's density-independent approach.
83
+
102
84
  ### Best Practice
103
85
 
104
86
  Always use `dp` for consistent sizing across devices:
@@ -183,6 +165,8 @@ Stacking order controlled by:
183
165
  - Addition order
184
166
  - `zIndex` property (higher = on top)
185
167
 
168
+ > **Android limitation**: `zIndex` is only supported by composite layouts. The `zIndex` property is ignored by horizontal and vertical layouts.
169
+
186
170
  ### Vertical Layout
187
171
 
188
172
  Children stack vertically:
@@ -281,6 +265,18 @@ const view = Ti.UI.createView({
281
265
  | Switch | WebView | |
282
266
  | TextField | ScrollableView | |
283
267
 
268
+ ### ScrollView Auto-Sizing
269
+
270
+ When a `ScrollView`'s `contentWidth` or `contentHeight` is set to `"auto"` or `Ti.UI.SIZE`, the scroll view's content area grows based on the bottom/right offsets of its child views:
271
+
272
+ ```javascript
273
+ const scrollView = Ti.UI.createScrollView({
274
+ contentWidth: 'auto',
275
+ contentHeight: 'auto',
276
+ layout: 'vertical'
277
+ });
278
+ ```
279
+
284
280
  ### Auto-Size in Layout Modes
285
281
 
286
282
  In `vertical`/`horizontal` layouts:
@@ -350,6 +346,18 @@ win.add(view1);
350
346
  win.add(view2); // view2 appears on top of view1
351
347
  ```
352
348
 
349
+ ### The `size` Property and `postlayout` Event
350
+
351
+ The read-only `size` property provides the width and height of a view after layout. This property won't return accurate values until a `postlayout` event has been received:
352
+
353
+ ```javascript
354
+ const view = Ti.UI.createView({ width: '50%', height: Ti.UI.SIZE });
355
+
356
+ view.addEventListener('postlayout', () => {
357
+ Ti.API.info(`Actual size: ${view.size.width}x${view.size.height}`);
358
+ });
359
+ ```
360
+
353
361
  ### Explicit Z-Index
354
362
 
355
363
  ```javascript
@@ -1,55 +1,5 @@
1
1
  # ListViews and Performance Optimization
2
2
 
3
- ## Table of Contents
4
-
5
- - [ListViews and Performance Optimization](#listviews-and-performance-optimization)
6
- - [Table of Contents](#table-of-contents)
7
- - [1. Overview](#1-overview)
8
- - [Core Concepts](#core-concepts)
9
- - [2. Basic ListView Structure](#2-basic-listview-structure)
10
- - [Declarative (Alloy XML)](#declarative-alloy-xml)
11
- - [Programmatic Data Binding](#programmatic-data-binding)
12
- - [Mapping External Data](#mapping-external-data)
13
- - [3. Templates](#3-templates)
14
- - [Default Template](#default-template)
15
- - [Custom Templates](#custom-templates)
16
- - [Multiple Templates](#multiple-templates)
17
- - [4. Data Binding](#4-data-binding)
18
- - [Binding Syntax](#binding-syntax)
19
- - [Programmatic Binding with Custom Templates](#programmatic-binding-with-custom-templates)
20
- - [5. Section Operations](#5-section-operations)
21
- - [CRUD Methods](#crud-methods)
22
- - [Example Operations](#example-operations)
23
- - [6. Events](#6-events)
24
- - [Item Click](#item-click)
25
- - [Marker Events (Infinite Scroll)](#marker-events-infinite-scroll)
26
- - [Template Element Events](#template-element-events)
27
- - [7. Critical Performance Rules](#7-critical-performance-rules)
28
- - [Rule 1: Avoid Ti.UI.SIZE in Templates](#rule-1-avoid-tiuisize-in-templates)
29
- - [Rule 2: Cannot Access Children Directly](#rule-2-cannot-access-children-directly)
30
- - [Rule 3: Minimize Template Count](#rule-3-minimize-template-count)
31
- - [Rule 4: Use updateItemAt for Changes](#rule-4-use-updateitemat-for-changes)
32
- - [Rule 5: Animations are Limited](#rule-5-animations-are-limited)
33
- - [8. iOS Action Items (Swipe Actions)](#8-ios-action-items-swipe-actions)
34
- - [9. Search](#9-search)
35
- - [10. Performance Best Practices](#10-performance-best-practices)
36
- - [DO:](#do)
37
- - [DON'T:](#dont)
38
- - [11. Transitioning from TableView](#11-transitioning-from-tableview)
39
- - [Core Logic Differences](#core-logic-differences)
40
- - [API Differences](#api-differences)
41
- - [12. Common Patterns](#12-common-patterns)
42
- - [Infinite Scroll with Markers](#infinite-scroll-with-markers)
43
- - [Multiple Selection](#multiple-selection)
44
- - [Section Index (A-Z)](#section-index-a-z)
45
- - [13. Platform Differences](#13-platform-differences)
46
- - [iOS vs Android](#ios-vs-android)
47
- - [cacheSize (iOS)](#cachesize-ios)
48
- - [14. Debugging](#14-debugging)
49
- - [Common Issues](#common-issues)
50
-
51
- ---
52
-
53
3
  ## 1. Overview
54
4
 
55
5
  ListView is a data-oriented, high-performance replacement for TableView. It optimizes large datasets by recycling native views and managing the item lifecycle automatically.
@@ -199,6 +149,34 @@ const items = [
199
149
  $.dynamicListView.sections[0].setItems(items);
200
150
  ```
201
151
 
152
+ ### iOS Built-in Templates (iOS Only)
153
+
154
+ iOS provides four built-in templates that can be used without defining custom `ItemTemplate`:
155
+
156
+ | Constant | Layout |
157
+ | ----------------------------------- | --------------------------------------------------------------- |
158
+ | `Ti.UI.LIST_ITEM_TEMPLATE_DEFAULT` | Left-justified title only (this is the default) |
159
+ | `Ti.UI.LIST_ITEM_TEMPLATE_SUBTITLE` | Title with subtitle below in smaller gray text |
160
+ | `Ti.UI.LIST_ITEM_TEMPLATE_SETTINGS` | Left-justified title on left, right-justified subtitle on right |
161
+ | `Ti.UI.LIST_ITEM_TEMPLATE_CONTACTS` | Right-justified title with left-justified subtitle |
162
+
163
+ ```javascript
164
+ const section = Ti.UI.createListSection({
165
+ items: [
166
+ { properties: { title: 'Title', subtitle: 'Subtitle' } }
167
+ ]
168
+ });
169
+
170
+ const listView = Ti.UI.createListView({
171
+ sections: [section],
172
+ defaultItemTemplate: Ti.UI.LIST_ITEM_TEMPLATE_SUBTITLE
173
+ });
174
+ ```
175
+
176
+ ### Supported Template View Classes
177
+
178
+ The following views can be used as child elements in custom templates: ActivityIndicator, Button, ImageView, Label, MaskedImage, ProgressBar, Slider, Switch, TextArea, TextField.
179
+
202
180
  ## 4. Data Binding
203
181
 
204
182
  ### Binding Syntax
@@ -260,6 +238,22 @@ section.replaceItemsAt(2, 3, replacementItems);
260
238
  section.deleteItemsAt(10, 2);
261
239
  ```
262
240
 
241
+ ### Row Animation (iOS)
242
+
243
+ You can pass animation styles to append/delete/insert/replace/update methods:
244
+
245
+ ```javascript
246
+ section.deleteItemsAt(0, 1, {
247
+ animationStyle: Ti.UI.iOS.RowAnimationStyle.LEFT
248
+ });
249
+
250
+ section.appendItems(newItems, {
251
+ animationStyle: Ti.UI.iOS.RowAnimationStyle.FADE
252
+ });
253
+ ```
254
+
255
+ Available styles: `Ti.UI.iOS.RowAnimationStyle.BOTTOM`, `FADE`, `LEFT`, `NONE`, `RIGHT`, `TOP`.
256
+
263
257
  ## 6. Events
264
258
 
265
259
  ### Item Click
@@ -309,6 +303,29 @@ function markerReached(e) {
309
303
  $.myList.addEventListener('marker', markerReached);
310
304
  ```
311
305
 
306
+ Since SDK 4.1.0, use `addMarker()` to add additional markers after the initial `setMarker()`:
307
+
308
+ ```javascript
309
+ $.myList.addMarker({ sectionIndex: 0, itemIndex: 149 });
310
+ ```
311
+
312
+ ### Scroll Events
313
+
314
+ Since SDK 4.1.0, use `scrollstart` and `scrollend` events to monitor scrolling:
315
+
316
+ ```javascript
317
+ $.myList.addEventListener('scrollstart', (e) => {
318
+ Ti.API.info(`Scroll started at section ${e.firstVisibleSectionIndex}, item ${e.firstVisibleItemIndex}`);
319
+ Ti.API.info(`Visible items: ${e.visibleItemCount}`);
320
+ });
321
+
322
+ $.myList.addEventListener('scrollend', (e) => {
323
+ Ti.API.info(`Scroll ended at section ${e.firstVisibleSectionIndex}, item ${e.firstVisibleItemIndex}`);
324
+ });
325
+ ```
326
+
327
+ Event properties: `firstVisibleSectionIndex`, `firstVisibleItemIndex`, `visibleItemCount`.
328
+
312
329
  ### Template Element Events
313
330
 
314
331
  ```xml
@@ -432,32 +449,71 @@ ListView items have limited animation support. For complex animations, consider
432
449
  ```javascript
433
450
  const section = $.myList.sections[0];
434
451
 
435
- // Define edit actions
436
- const deleteAction = Ti.UI.iOS.createListViewDeleteOptions({
437
- title: 'Delete'
438
- });
439
-
440
- const moreAction = Ti.UI.iOS.createListViewEditAction({
441
- title: 'More',
442
- backgroundColor: 'blue',
443
- style: Ti.UI.iOS.LIST_VIEW_EDIT_ACTION_STYLE_NORMAL
444
- });
445
-
446
- // Enable editing
447
- section.editActions = [deleteAction, moreAction];
452
+ // Define edit actions as plain objects with title, style, and optional color
453
+ section.editActions = [
454
+ {
455
+ title: 'Delete',
456
+ style: Ti.UI.iOS.ROW_ACTION_STYLE_DESTRUCTIVE
457
+ },
458
+ {
459
+ title: 'More',
460
+ color: 'blue',
461
+ style: Ti.UI.iOS.ROW_ACTION_STYLE_NORMAL
462
+ }
463
+ ];
448
464
  section.canEdit = true;
449
465
 
450
- // Handle actions
466
+ // Handle actions — e.action is the title STRING of the tapped action
451
467
  $.myList.addEventListener('editaction', (e) => {
452
- if (e.action === deleteAction) {
453
- section.deleteItemsAt(e.itemIndex, 1);
454
- } else if (e.action === moreAction) {
468
+ if (e.action === 'Delete') {
469
+ e.section.deleteItemsAt(e.itemIndex, 1);
470
+ } else if (e.action === 'More') {
455
471
  // Handle more action
472
+ Ti.API.info(`More tapped on item ${e.itemIndex} in section ${e.sectionIndex}`);
456
473
  }
457
474
  });
458
475
  ```
459
476
 
460
- ## 9. Search
477
+ **Available action styles:**
478
+ - `Ti.UI.iOS.ROW_ACTION_STYLE_DEFAULT` — gray background
479
+ - `Ti.UI.iOS.ROW_ACTION_STYLE_DESTRUCTIVE` — red background (default)
480
+ - `Ti.UI.iOS.ROW_ACTION_STYLE_NORMAL` — custom color background
481
+
482
+ **Event properties:** `action` (string — the title), `itemId`, `itemIndex`, `section`, `sectionIndex`.
483
+
484
+ ## 9. Editing Mode (iOS)
485
+
486
+ Set the `editing` property to toggle edit mode, allowing users to delete and reorder items:
487
+
488
+ ```javascript
489
+ // Toggle edit mode
490
+ $.myList.editing = true;
491
+
492
+ // Auto-remove sections that become empty during editing
493
+ $.myList.pruneSectionsOnEdit = true;
494
+ ```
495
+
496
+ ### Delete Event
497
+
498
+ Fires when a user deletes an item in edit mode:
499
+
500
+ ```javascript
501
+ $.myList.addEventListener('delete', (e) => {
502
+ Ti.API.info(`Deleted item ${e.itemIndex} from section ${e.sectionIndex}`);
503
+ });
504
+ ```
505
+
506
+ ### Move Event
507
+
508
+ Fires when a user reorders an item in edit mode:
509
+
510
+ ```javascript
511
+ $.myList.addEventListener('move', (e) => {
512
+ Ti.API.info(`Moved item from ${e.itemIndex} to ${e.targetItemIndex}`);
513
+ });
514
+ ```
515
+
516
+ ## 10. Search
461
517
 
462
518
  ```javascript
463
519
  const searchView = Ti.UI.createSearchBar({
@@ -477,7 +533,30 @@ const items = [
477
533
  ];
478
534
  ```
479
535
 
480
- ## 10. Performance Best Practices
536
+ ### Search Properties
537
+
538
+ - `keepSectionsInSearch: true` — preserves section headers while filtering search results.
539
+ - `caseInsensitiveSearch: true` — enables case-insensitive search filtering.
540
+
541
+ ```javascript
542
+ const listView = Ti.UI.createListView({
543
+ searchView: searchView,
544
+ keepSectionsInSearch: true,
545
+ caseInsensitiveSearch: true
546
+ });
547
+ ```
548
+
549
+ ### No Results Event
550
+
551
+ Since SDK 3.3.0, when items are filtered using `searchView` or `searchText`, the `noresults` event fires when search returns no results:
552
+
553
+ ```javascript
554
+ $.myList.addEventListener('noresults', (e) => {
555
+ Ti.API.info('No matching items found');
556
+ });
557
+ ```
558
+
559
+ ## 11. Performance Best Practices
481
560
 
482
561
  ### DO:
483
562
  - Use fixed heights in templates
@@ -494,7 +573,7 @@ const items = [
494
573
  - Add complex animations to list items
495
574
  - Ignore the "recycled" nature of views
496
575
 
497
- ## 11. Transitioning from TableView
576
+ ## 12. Transitioning from TableView
498
577
 
499
578
  ### Core Logic Differences
500
579
 
@@ -522,7 +601,7 @@ const items = [
522
601
  - `appendRow`, `deleteRow`, `deselectRow`, `insertRowAfter`, `insertRowBefore`, `selectRow`, `updateRow`, `scrollToIndex`.
523
602
  - *Alternatives*: Use `scrollToItem` and `selectItem` (iOS). For row manipulation, use the containing `ListSection`.
524
603
 
525
- ## 12. Common Patterns
604
+ ## 13. Common Patterns
526
605
 
527
606
  ### Infinite Scroll with Markers
528
607
 
@@ -583,7 +662,7 @@ $.myList.addEventListener('itemclick', (e) => {
583
662
  $.myList.sectionIndexTitles = ["A", "B", "C", ...];
584
663
  ```
585
664
 
586
- ## 13. Platform Differences
665
+ ## 14. Platform Differences
587
666
 
588
667
  ### iOS vs Android
589
668
 
@@ -595,6 +674,41 @@ $.myList.sectionIndexTitles = ["A", "B", "C", ...];
595
674
  | Default template image | Left side | Right side |
596
675
  | cacheSize property | Supported | Not supported |
597
676
 
677
+ ### Grouped Style (iOS)
678
+
679
+ Set `style: Ti.UI.iOS.ListViewStyle.GROUPED` to display sections as separate visual groups with rounded corners and inset spacing:
680
+
681
+ ```javascript
682
+ const listView = Ti.UI.createListView({
683
+ style: Ti.UI.iOS.ListViewStyle.GROUPED,
684
+ sections: [sectionA, sectionB]
685
+ });
686
+ ```
687
+
688
+ ### Pull-to-Refresh (iOS)
689
+
690
+ The `pull` event fires when the user pulls past the top of the list, and `pullend` fires when the user releases. Use the `pullView` property to set a custom pull-to-refresh view:
691
+
692
+ ```javascript
693
+ const pullView = Ti.UI.createView({
694
+ height: 60,
695
+ backgroundColor: '#eee'
696
+ });
697
+ pullView.add(Ti.UI.createLabel({ text: 'Pull to refresh...' }));
698
+
699
+ $.myList.pullView = pullView;
700
+
701
+ $.myList.addEventListener('pull', (e) => {
702
+ // User is pulling — update UI as needed
703
+ pullView.children[0].text = e.active ? 'Release to refresh...' : 'Pull to refresh...';
704
+ });
705
+
706
+ $.myList.addEventListener('pullend', (e) => {
707
+ // User released — trigger data refresh
708
+ refreshData();
709
+ });
710
+ ```
711
+
598
712
  ### cacheSize (iOS)
599
713
 
600
714
  ```javascript
@@ -602,7 +716,7 @@ $.myList.sectionIndexTitles = ["A", "B", "C", ...];
602
716
  $.myList.cacheSize = 3; // Default
603
717
  ```
604
718
 
605
- ## 14. Debugging
719
+ ## 15. Debugging
606
720
 
607
721
  ### Common Issues
608
722