@maccesar/titools 2.2.12 → 2.4.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.
- package/README.md +255 -713
- package/bin/titools.js +9 -1
- package/lib/cache.js +49 -0
- package/lib/commands/auto-update.js +138 -0
- package/lib/commands/skills.js +11 -0
- package/lib/commands/uninstall.js +17 -1
- package/lib/commands/update.js +5 -6
- package/lib/config.js +3 -0
- package/lib/downloader.js +10 -0
- package/lib/hooks.js +59 -0
- package/lib/utils.js +1 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +46 -48
- package/skills/alloy-guides/references/CONTROLLERS.md +4 -6
- package/skills/alloy-guides/references/MODELS.md +340 -184
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +3 -4
- package/skills/alloy-guides/references/VIEWS_STYLES.md +44 -46
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +4 -5
- package/skills/alloy-guides/references/VIEWS_XML.md +51 -17
- package/skills/alloy-guides/references/WIDGETS.md +1 -1
- package/skills/alloy-howtos/SKILL.md +12 -13
- package/skills/alloy-howtos/references/cli_reference.md +40 -41
- package/skills/alloy-howtos/references/samples.md +3 -4
- package/skills/purgetss/SKILL.md +369 -356
- package/skills/purgetss/references/EXAMPLES.md +24 -25
- package/skills/purgetss/references/animation-advanced.md +555 -0
- package/skills/purgetss/references/animation-system.md +395 -995
- package/skills/purgetss/references/apply-directive.md +111 -141
- package/skills/purgetss/references/arbitrary-values.md +206 -480
- package/skills/purgetss/references/class-categories.md +277 -0
- package/skills/purgetss/references/class-index.md +1 -420
- package/skills/purgetss/references/cli-commands.md +446 -556
- package/skills/purgetss/references/configurable-properties.md +163 -599
- package/skills/purgetss/references/custom-rules.md +33 -76
- package/skills/purgetss/references/customization-deep-dive.md +319 -518
- package/skills/purgetss/references/dynamic-component-creation.md +33 -37
- package/skills/purgetss/references/grid-layout.md +42 -371
- package/skills/purgetss/references/icon-fonts.md +82 -475
- package/skills/purgetss/references/installation-setup.md +159 -331
- package/skills/purgetss/references/migration-guide.md +54 -109
- package/skills/purgetss/references/opacity-modifier.md +25 -222
- package/skills/purgetss/references/performance-tips.md +2 -2
- package/skills/purgetss/references/platform-modifiers.md +21 -407
- package/skills/purgetss/references/tikit-components.md +237 -104
- package/skills/purgetss/references/titanium-resets.md +20 -21
- package/skills/purgetss/references/ui-ux-design.md +171 -1702
- package/skills/ti-api/SKILL.md +109 -0
- package/skills/ti-api/references/api-android.md +675 -0
- package/skills/ti-api/references/api-app-platform.md +636 -0
- package/skills/ti-api/references/api-core.md +764 -0
- package/skills/ti-api/references/api-data-network.md +641 -0
- package/skills/ti-api/references/api-media.md +655 -0
- package/skills/ti-api/references/api-modules-ble-bluetooth.md +657 -0
- package/skills/ti-api/references/api-modules-coremotion-urlsession.md +411 -0
- package/skills/ti-api/references/api-modules-map.md +632 -0
- package/skills/ti-api/references/api-modules-nfc.md +725 -0
- package/skills/ti-api/references/api-modules-social-misc.md +526 -0
- package/skills/ti-api/references/api-services.md +700 -0
- package/skills/ti-api/references/api-ui-android.md +499 -0
- package/skills/ti-api/references/api-ui-extras.md +702 -0
- package/skills/ti-api/references/api-ui-ios-animator.md +378 -0
- package/skills/ti-api/references/api-ui-ios.md +756 -0
- package/skills/ti-api/references/api-ui-lists.md +581 -0
- package/skills/ti-api/references/api-ui-text-input.md +607 -0
- package/skills/ti-api/references/api-ui-views.md +572 -0
- package/skills/ti-api/references/api-ui-windows-navigation.md +676 -0
- package/skills/ti-api/references/api-xml-global.md +743 -0
- package/skills/ti-expert/SKILL.md +46 -45
- package/skills/ti-expert/references/adaptive-layouts.md +414 -0
- package/skills/ti-expert/references/alloy-builtins.md +16 -20
- package/skills/ti-expert/references/alloy-structure.md +40 -42
- package/skills/ti-expert/references/anti-patterns.md +34 -0
- package/skills/ti-expert/references/code-conventions.md +5 -3
- package/skills/ti-expert/references/error-handling.md +14 -7
- package/skills/ti-expert/references/examples.md +4 -2
- package/skills/ti-expert/references/performance-optimization.md +26 -24
- package/skills/ti-expert/references/security-device.md +17 -14
- package/skills/ti-expert/references/security-fundamentals.md +60 -101
- package/skills/ti-expert/references/state-management.md +15 -14
- package/skills/ti-expert/references/testing-e2e-ci.md +30 -21
- package/skills/ti-expert/references/theming.md +12 -20
- package/skills/ti-guides/SKILL.md +13 -17
- package/skills/ti-guides/references/advanced-data-and-images.md +30 -10
- package/skills/ti-guides/references/application-frameworks.md +3 -3
- package/skills/ti-guides/references/coding-best-practices.md +31 -2
- package/skills/ti-guides/references/commonjs-advanced.md +46 -4
- package/skills/ti-guides/references/hello-world.md +9 -13
- package/skills/ti-guides/references/hyperloop-native-access.md +4 -1
- package/skills/ti-guides/references/javascript-primer.md +13 -5
- package/skills/ti-guides/references/resources.md +0 -2
- package/skills/ti-guides/references/style-and-conventions.md +1 -0
- package/skills/ti-guides/references/tiapp-config.md +0 -32
- package/skills/ti-howtos/SKILL.md +43 -45
- package/skills/ti-howtos/references/buffer-codec-streams.md +25 -3
- package/skills/ti-howtos/references/debugging-profiling.md +14 -25
- package/skills/ti-howtos/references/google-maps-v2.md +3 -3
- package/skills/ti-howtos/references/ios-map-kit.md +8 -1
- package/skills/ti-howtos/references/notification-services.md +0 -1
- package/skills/ti-howtos/references/webpack-build-pipeline.md +3 -0
- package/skills/ti-ui/SKILL.md +47 -49
- package/skills/ti-ui/references/application-structures.md +3 -2
- package/skills/ti-ui/references/orientation.md +17 -9
- package/skills/ti-ui/references/platform-ui-ios.md +63 -0
- package/skills/ti-ui/references/scrolling-views.md +39 -0
|
@@ -8,11 +8,17 @@ Buffers are mutable, resizable containers for bytes (byte arrays).
|
|
|
8
8
|
|
|
9
9
|
### Creating buffers
|
|
10
10
|
```javascript
|
|
11
|
+
// Empty buffer (initial length 0)
|
|
12
|
+
const buffer0 = Ti.createBuffer();
|
|
13
|
+
|
|
11
14
|
// Empty 512-byte buffer
|
|
12
15
|
const buffer1 = Ti.createBuffer({ length: 512 });
|
|
13
16
|
|
|
14
17
|
// Buffer initialized with a string (UTF-8 by default)
|
|
15
18
|
const buffer2 = Ti.createBuffer({ value: 'Hello World' });
|
|
19
|
+
|
|
20
|
+
// Buffer initialized with explicit charset
|
|
21
|
+
const buffer3 = Ti.createBuffer({ value: 'Hello World', type: Ti.Codec.CHARSET_UTF16 });
|
|
16
22
|
```
|
|
17
23
|
|
|
18
24
|
### Common operations
|
|
@@ -20,14 +26,18 @@ const buffer2 = Ti.createBuffer({ value: 'Hello World' });
|
|
|
20
26
|
const b1 = Ti.createBuffer({ value: 'Part 1. ' });
|
|
21
27
|
const b2 = Ti.createBuffer({ value: 'Part 2.' });
|
|
22
28
|
|
|
23
|
-
// Append
|
|
29
|
+
// Append (resizes b1)
|
|
24
30
|
b1.append(b2);
|
|
25
31
|
|
|
32
|
+
// Insert at position (resizes buffer as needed)
|
|
33
|
+
const extra = Ti.createBuffer({ value: 'X' });
|
|
34
|
+
b1.insert(extra, 1); // insert extra at index 1
|
|
35
|
+
|
|
26
36
|
// Truncate
|
|
27
37
|
b1.length = 10;
|
|
28
38
|
|
|
29
|
-
// Direct access
|
|
30
|
-
b1[0] = 72; // 'H'
|
|
39
|
+
// Direct array access — buffer is NOT auto-extended; values must be byte values
|
|
40
|
+
b1[0] = 72; // 'H' (ASCII). b1[100] = 1 would throw if index >= b1.length
|
|
31
41
|
|
|
32
42
|
// Free memory
|
|
33
43
|
b1.release();
|
|
@@ -48,6 +58,18 @@ Ti.Codec.encodeNumber({
|
|
|
48
58
|
});
|
|
49
59
|
```
|
|
50
60
|
|
|
61
|
+
### Encoding strings
|
|
62
|
+
```javascript
|
|
63
|
+
// Encode a string into a buffer; returns the byte length written
|
|
64
|
+
const buffer = Ti.createBuffer({ length: 1024 });
|
|
65
|
+
const encodedLength = Ti.Codec.encodeString({
|
|
66
|
+
source: 'hello world',
|
|
67
|
+
dest: buffer
|
|
68
|
+
});
|
|
69
|
+
// Trim buffer to actual content
|
|
70
|
+
buffer.length = encodedLength;
|
|
71
|
+
```
|
|
72
|
+
|
|
51
73
|
### Decoding strings
|
|
52
74
|
```javascript
|
|
53
75
|
const text = Ti.Codec.decodeString({
|
|
@@ -180,11 +180,11 @@ Setup:
|
|
|
180
180
|
5. Click Record
|
|
181
181
|
|
|
182
182
|
Key columns:
|
|
183
|
-
| Column
|
|
184
|
-
|
|
|
185
|
-
| Persistent Bytes (Live Bytes)
|
|
186
|
-
| #Persistent (#Living)
|
|
187
|
-
| #Transient (#Transitory)
|
|
183
|
+
| Column | What it shows |
|
|
184
|
+
| ----------------------------- | ------------------------ |
|
|
185
|
+
| Persistent Bytes (Live Bytes) | Memory currently in use |
|
|
186
|
+
| #Persistent (#Living) | Active object count |
|
|
187
|
+
| #Transient (#Transitory) | Ready to garbage collect |
|
|
188
188
|
|
|
189
189
|
Identifying leaks:
|
|
190
190
|
1. Filter for `Ti` prefix (Titanium objects)
|
|
@@ -348,27 +348,22 @@ SELECT * FROM tablename;
|
|
|
348
348
|
|
|
349
349
|
### Creating emulators
|
|
350
350
|
|
|
351
|
-
|
|
351
|
+
> **⚠️ AVD Manager moved to Android Studio**
|
|
352
|
+
> The legacy `android` CLI (`android create avd`, `android avd`) was removed in Android SDK Tools 25.3. Use Android Studio's built-in **AVD Manager** (Tools → Device Manager) or the command-line `avdmanager` tool instead.
|
|
353
|
+
|
|
354
|
+
Command line (modern):
|
|
352
355
|
```bash
|
|
353
|
-
# List available
|
|
354
|
-
|
|
356
|
+
# List available system images
|
|
357
|
+
sdkmanager --list | grep system-images
|
|
355
358
|
|
|
356
|
-
# Create AVD
|
|
357
|
-
|
|
359
|
+
# Create AVD with avdmanager
|
|
360
|
+
avdmanager create avd -n my_emulator -k "system-images;android-34;google_apis;x86_64"
|
|
358
361
|
|
|
359
362
|
# Launch emulator
|
|
360
363
|
emulator -avd my_emulator
|
|
361
364
|
```
|
|
362
365
|
|
|
363
|
-
|
|
364
|
-
```bash
|
|
365
|
-
android avd
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
1. Click New
|
|
369
|
-
2. Enter name, select device/target
|
|
370
|
-
3. Choose x86 ABI if available
|
|
371
|
-
4. Click OK
|
|
366
|
+
Android Studio (GUI): Tools → Device Manager → Create Device.
|
|
372
367
|
|
|
373
368
|
### Modifying emulators
|
|
374
369
|
|
|
@@ -378,12 +373,6 @@ Edit `~/.android/avd/<NAME>.avd/config.ini`:
|
|
|
378
373
|
disk.dataPartition.size=1024m
|
|
379
374
|
```
|
|
380
375
|
|
|
381
|
-
Resize emulator:
|
|
382
|
-
1. Close emulator
|
|
383
|
-
2. AVD Manager → Select emulator → Edit
|
|
384
|
-
3. Change resolution
|
|
385
|
-
4. Save
|
|
386
|
-
|
|
387
376
|
Scale on-the-fly:
|
|
388
377
|
```bash
|
|
389
378
|
# Get emulator port
|
|
@@ -143,13 +143,13 @@ mapView.addEventListener('click', (e) => {
|
|
|
143
143
|
});
|
|
144
144
|
|
|
145
145
|
// Detect drag state changes
|
|
146
|
+
// e.newState holds the drag state constant; e.annotation holds the annotation object
|
|
146
147
|
mapView.addEventListener('pinchangedragstate', (e) => {
|
|
147
|
-
if (e.
|
|
148
|
+
if (e.newState === MapModule.ANNOTATION_DRAG_STATE_END) {
|
|
148
149
|
Ti.API.info(`Dropped at: ${e.annotation.latitude}, ${e.annotation.longitude}`);
|
|
149
150
|
}
|
|
150
151
|
});
|
|
151
|
-
// Drag states: ANNOTATION_DRAG_STATE_START,
|
|
152
|
-
// ANNOTATION_DRAG_STATE_CANCEL, ANNOTATION_DRAG_STATE_END
|
|
152
|
+
// Drag states: ANNOTATION_DRAG_STATE_START, ANNOTATION_DRAG_STATE_END
|
|
153
153
|
|
|
154
154
|
// Detect region changes
|
|
155
155
|
mapView.addEventListener('regionchanged', (e) => {
|
|
@@ -77,6 +77,12 @@ mapView.showsBuildings = true; // 3D buildings
|
|
|
77
77
|
|
|
78
78
|
## 4. iOS annotations
|
|
79
79
|
|
|
80
|
+
### iOS pin colors
|
|
81
|
+
iOS supports only three pin color constants (unlike Android's ten):
|
|
82
|
+
- `MapModule.ANNOTATION_GREEN`
|
|
83
|
+
- `MapModule.ANNOTATION_PURPLE`
|
|
84
|
+
- `MapModule.ANNOTATION_RED`
|
|
85
|
+
|
|
80
86
|
### System buttons and callouts
|
|
81
87
|
iOS allows native buttons in the pin callout (popup window).
|
|
82
88
|
|
|
@@ -134,8 +140,9 @@ mapView.addEventListener('click', (e) => {
|
|
|
134
140
|
}
|
|
135
141
|
});
|
|
136
142
|
|
|
143
|
+
// e.newState holds the drag state constant; e.annotation holds the annotation object
|
|
137
144
|
mapView.addEventListener('pinchangedragstate', (e) => {
|
|
138
|
-
if (e.
|
|
145
|
+
if (e.newState === MapModule.ANNOTATION_DRAG_STATE_END) {
|
|
139
146
|
Ti.API.info(`Dropped at: ${e.annotation.latitude}, ${e.annotation.longitude}`);
|
|
140
147
|
}
|
|
141
148
|
});
|
|
@@ -531,7 +531,6 @@ Use `UNMutableNotificationContent` with attachments (images, video, audio).
|
|
|
531
531
|
|
|
532
532
|
- Service lifecycle: services may be killed if app is swiped away. For critical notifications, use FCM instead of local services.
|
|
533
533
|
- Notification channels: Android 8.0+ requires notification channels.
|
|
534
|
-
- Limitations: legacy MapView only supports a single map view.
|
|
535
534
|
|
|
536
535
|
### iOS
|
|
537
536
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Webpack build pipeline
|
|
2
2
|
|
|
3
|
+
> **⚠️ Appcelerator/Axway era feature**
|
|
4
|
+
> The Webpack pipeline documented here was introduced with Titanium SDK 9.1.0 as part of the Axway AMPLIFY toolchain (`appcd` daemon). Since Axway discontinued Appcelerator, this feature is **not maintained** in the current TiDev CLI (`ti`). If you are using the community TiDev CLI, this pipeline may not be available. Prefer the standard `ti build` pipeline unless your project already uses Webpack.
|
|
5
|
+
|
|
3
6
|
Webpack integration is an alternative build pipeline starting with Titanium SDK 9.1.0. It is optional. When enabled, Webpack manages asset and code bundling.
|
|
4
7
|
|
|
5
8
|
## 1. Key benefits
|
package/skills/ti-ui/SKILL.md
CHANGED
|
@@ -11,22 +11,21 @@ A practical guide to Titanium SDK UI. Covers layouts, event handling, animations
|
|
|
11
11
|
|
|
12
12
|
## Project detection
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
This skill detects Titanium projects and provides UI guidance.
|
|
16
|
-
|
|
17
|
-
Detection happens automatically. You do not need to run a command.
|
|
18
|
-
|
|
19
|
-
Titanium project indicator:
|
|
20
|
-
- `tiapp.xml` (required for all Titanium projects)
|
|
21
|
-
|
|
22
|
-
Applicable to both:
|
|
23
|
-
- Alloy projects (app/ folder structure)
|
|
24
|
-
- Classic projects (Resources/ folder)
|
|
25
|
-
|
|
26
|
-
Behavior based on detection:
|
|
27
|
-
- Titanium detected: Provide UI guidance for Alloy and Classic, ListView/TableView patterns, and platform differences
|
|
28
|
-
- Not detected: State this is for Titanium projects only and skip UI guidance
|
|
29
|
-
:::
|
|
14
|
+
> **️ℹ️ auto-detects titanium projects**
|
|
15
|
+
> This skill detects Titanium projects and provides UI guidance.
|
|
16
|
+
>
|
|
17
|
+
> Detection happens automatically. You do not need to run a command.
|
|
18
|
+
>
|
|
19
|
+
> Titanium project indicator:
|
|
20
|
+
> - `tiapp.xml` (required for all Titanium projects)
|
|
21
|
+
>
|
|
22
|
+
> Applicable to both:
|
|
23
|
+
> - Alloy projects (app/ folder structure)
|
|
24
|
+
> - Classic projects (Resources/ folder)
|
|
25
|
+
>
|
|
26
|
+
> Behavior based on detection:
|
|
27
|
+
> - Titanium detected: Provide UI guidance for Alloy and Classic, ListView/TableView patterns, and platform differences
|
|
28
|
+
> - Not detected: State this is for Titanium projects only and skip UI guidance
|
|
30
29
|
|
|
31
30
|
## Quick reference
|
|
32
31
|
|
|
@@ -65,39 +64,38 @@ Behavior based on detection:
|
|
|
65
64
|
|
|
66
65
|
### Platform-specific properties
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties without platform modifiers will crash cross-platform compilation.
|
|
70
|
-
|
|
71
|
-
Example of the damage:
|
|
72
|
-
```javascript
|
|
73
|
-
// Wrong: adds Ti.UI.iOS to an Android build
|
|
74
|
-
const win = Ti.UI.createWindow({
|
|
75
|
-
|
|
76
|
-
})
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Correct approaches:
|
|
80
|
-
|
|
81
|
-
Option 1: TSS modifier (Alloy projects):
|
|
82
|
-
```tss
|
|
83
|
-
"#mainWindow[platform=ios]": {
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Option 2: Conditional code:
|
|
89
|
-
```javascript
|
|
90
|
-
if (OS_IOS) {
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Properties that always require platform modifiers:
|
|
96
|
-
- iOS: `statusBarStyle`, `modalStyle`, `modalTransitionStyle`, any `Ti.UI.iOS.*`
|
|
97
|
-
- Android: `actionBar` config, any `Ti.UI.Android.*` constant
|
|
98
|
-
|
|
99
|
-
For platform-specific UI patterns, see [platform-ui-ios.md](references/platform-ui-ios.md) and [platform-ui-android.md](references/platform-ui-android.md).
|
|
100
|
-
:::
|
|
67
|
+
> **🚨 critical: platform-specific properties require modifiers**
|
|
68
|
+
> Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties without platform modifiers will crash cross-platform compilation.
|
|
69
|
+
>
|
|
70
|
+
> Example of the damage:
|
|
71
|
+
> ```javascript
|
|
72
|
+
> // Wrong: adds Ti.UI.iOS to an Android build
|
|
73
|
+
> const win = Ti.UI.createWindow({
|
|
74
|
+
> statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT
|
|
75
|
+
> })
|
|
76
|
+
> ```
|
|
77
|
+
>
|
|
78
|
+
> Correct approaches:
|
|
79
|
+
>
|
|
80
|
+
> Option 1: TSS modifier (Alloy projects):
|
|
81
|
+
> ```tss
|
|
82
|
+
> "#mainWindow[platform=ios]": {
|
|
83
|
+
> statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT
|
|
84
|
+
> }
|
|
85
|
+
> ```
|
|
86
|
+
>
|
|
87
|
+
> Option 2: Conditional code:
|
|
88
|
+
> ```javascript
|
|
89
|
+
> if (OS_IOS) {
|
|
90
|
+
> $.mainWindow.statusBarStyle = Ti.UI.iOS.StatusBar.LIGHT_CONTENT
|
|
91
|
+
> }
|
|
92
|
+
> ```
|
|
93
|
+
>
|
|
94
|
+
> Properties that always require platform modifiers:
|
|
95
|
+
> - iOS: `statusBarStyle`, `modalStyle`, `modalTransitionStyle`, any `Ti.UI.iOS.*`
|
|
96
|
+
> - Android: `actionBar` config, any `Ti.UI.Android.*` constant
|
|
97
|
+
>
|
|
98
|
+
> For platform-specific UI patterns, see [platform-ui-ios.md](references/platform-ui-ios.md) and [platform-ui-android.md](references/platform-ui-android.md).
|
|
101
99
|
|
|
102
100
|
### Event management
|
|
103
101
|
- Remove global listeners (`Ti.App`, `Ti.Gesture`, `Ti.Accelerometer`) on pause to save battery.
|
|
@@ -259,7 +259,8 @@ tabGroup.addTab(Ti.UI.createTab({
|
|
|
259
259
|
|
|
260
260
|
tabGroup.open();
|
|
261
261
|
```
|
|
262
|
-
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
263
264
|
// Window-based app with NavigationWindow (iOS)
|
|
264
265
|
const navWindow = Ti.UI.createNavigationWindow({
|
|
265
266
|
window: Ti.UI.createWindow({
|
|
@@ -485,7 +486,7 @@ tabGroup.open();
|
|
|
485
486
|
|
|
486
487
|
SplitWindow (iPad):
|
|
487
488
|
```javascript
|
|
488
|
-
const splitWin = Ti.UI.
|
|
489
|
+
const splitWin = Ti.UI.iPad.createSplitWindow({
|
|
489
490
|
masterView: masterWindow,
|
|
490
491
|
detailView: detailWindow
|
|
491
492
|
});
|
|
@@ -50,12 +50,16 @@ iOS plist iPhone vs iPad keys: You can define separate orientations for iPhone a
|
|
|
50
50
|
- `UISupportedInterfaceOrientations~ipad` for iPad (default: all four)
|
|
51
51
|
- `UISupportedInterfaceOrientations` applies to both if device-specific keys are absent
|
|
52
52
|
|
|
53
|
+
The `<activity>` element must include `android:name` and be nested inside `<application>`. Titanium generates the main activity name as `<app-id>.<Appname>Activity`.
|
|
54
|
+
|
|
53
55
|
```xml
|
|
54
|
-
<android>
|
|
56
|
+
<android xmlns:android="http://schemas.android.com/apk/res/android">
|
|
55
57
|
<manifest>
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
|
|
58
|
+
<application>
|
|
59
|
+
<activity
|
|
60
|
+
android:name="com.example.myapp.MyappActivity"
|
|
61
|
+
android:screenOrientation="portrait"/>
|
|
62
|
+
</application>
|
|
59
63
|
</manifest>
|
|
60
64
|
</android>
|
|
61
65
|
```
|
|
@@ -111,9 +115,9 @@ Ti.Gesture.addEventListener('orientationchange', (e) => {
|
|
|
111
115
|
adjustForLandscape();
|
|
112
116
|
}
|
|
113
117
|
|
|
114
|
-
// Ti.Gesture
|
|
115
|
-
Ti.API.info(`Is portrait: ${e.source.
|
|
116
|
-
Ti.API.info(`Is landscape: ${e.source.
|
|
118
|
+
// Ti.Gesture convenience boolean properties
|
|
119
|
+
Ti.API.info(`Is portrait: ${e.source.portrait}`);
|
|
120
|
+
Ti.API.info(`Is landscape: ${e.source.landscape}`);
|
|
117
121
|
});
|
|
118
122
|
```
|
|
119
123
|
|
|
@@ -252,9 +256,13 @@ iOS (tiapp.xml):
|
|
|
252
256
|
|
|
253
257
|
Android (tiapp.xml):
|
|
254
258
|
```xml
|
|
255
|
-
<android>
|
|
259
|
+
<android xmlns:android="http://schemas.android.com/apk/res/android">
|
|
256
260
|
<manifest>
|
|
257
|
-
<
|
|
261
|
+
<application>
|
|
262
|
+
<activity
|
|
263
|
+
android:name="com.example.myapp.MyappActivity"
|
|
264
|
+
android:screenOrientation="portrait"/>
|
|
265
|
+
</application>
|
|
258
266
|
</manifest>
|
|
259
267
|
</android>
|
|
260
268
|
```
|
|
@@ -341,6 +341,69 @@ win2.close();
|
|
|
341
341
|
win1.navBarHidden = true;
|
|
342
342
|
```
|
|
343
343
|
|
|
344
|
+
## Community-Discovered Patterns
|
|
345
|
+
|
|
346
|
+
### Large Titles + ScrollView: required property triad (iOS)
|
|
347
|
+
|
|
348
|
+
When using `largeTitleEnabled: true` with a `ScrollView` inside a `NavigationWindow`, three Window properties must be set together. Without all three, the ScrollView content overlaps behind the navigation bar.
|
|
349
|
+
|
|
350
|
+
```javascript
|
|
351
|
+
const win = Ti.UI.createWindow({
|
|
352
|
+
title: 'My Screen',
|
|
353
|
+
largeTitleEnabled: true,
|
|
354
|
+
largeTitleDisplayMode: Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_AUTOMATIC,
|
|
355
|
+
extendEdges: [Ti.UI.EXTEND_EDGE_ALL],
|
|
356
|
+
autoAdjustScrollViewInsets: true,
|
|
357
|
+
barColor: '#1e293b',
|
|
358
|
+
backgroundColor: '#0f172a'
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const scrollView = Ti.UI.createScrollView({
|
|
362
|
+
layout: 'vertical',
|
|
363
|
+
contentWidth: Ti.UI.FILL,
|
|
364
|
+
contentHeight: Ti.UI.SIZE
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
scrollView.add(Ti.UI.createLabel({ text: 'Content here' }));
|
|
368
|
+
win.add(scrollView);
|
|
369
|
+
navWindow.openWindow(win);
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
| Property | Purpose | What breaks without it |
|
|
373
|
+
|---|---|---|
|
|
374
|
+
| `largeTitleEnabled: true` | Large title that collapses on scroll | No large title behavior |
|
|
375
|
+
| `extendEdges: [Ti.UI.EXTEND_EDGE_ALL]` | Content renders behind bars (blur/translucent effect) | Large title renders with visible delay (empty nav bar gap appears first, then title draws) |
|
|
376
|
+
| `autoAdjustScrollViewInsets: true` | Automatically adjusts ScrollView insets | Content overlaps behind the nav bar |
|
|
377
|
+
|
|
378
|
+
> **Why all three?** `extendEdges` tells iOS to extend content behind the navigation bar. `autoAdjustScrollViewInsets` tells iOS to compensate by adjusting the ScrollView's content insets so content starts below the bar. Without `extendEdges`, there is nothing to adjust — and the large title renders with a visible delay as iOS cannot calculate the full layout upfront. Without `autoAdjustScrollViewInsets`, the content sits behind the bar. They are interdependent.
|
|
379
|
+
|
|
380
|
+
`largeTitleDisplayMode` controls collapse behavior:
|
|
381
|
+
- `LARGE_TITLE_DISPLAY_MODE_AUTOMATIC` (default) — inherits from previous window; collapses on scroll
|
|
382
|
+
- `LARGE_TITLE_DISPLAY_MODE_ALWAYS` — title stays large regardless of scroll position
|
|
383
|
+
- `LARGE_TITLE_DISPLAY_MODE_NEVER` — always standard title size
|
|
384
|
+
|
|
385
|
+
#### Works with both NavigationWindow and TabGroup
|
|
386
|
+
|
|
387
|
+
On iOS, TabGroup wraps each Tab in an implicit NavigationWindow. The same three properties apply to Windows inside both standalone NavigationWindow and TabGroup Tabs. Child windows opened via `navWindow.openWindow()` or from within a Tab inherit the large title behavior when using `LARGE_TITLE_DISPLAY_MODE_AUTOMATIC`.
|
|
388
|
+
|
|
389
|
+
#### Recommended: global defaults
|
|
390
|
+
|
|
391
|
+
Instead of repeating the properties on every Window, set them as global defaults:
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
// app.tss (Alloy)
|
|
395
|
+
'Window[platform=ios]': {
|
|
396
|
+
autoAdjustScrollViewInsets: true,
|
|
397
|
+
extendEdges: [Ti.UI.EXTEND_EDGE_ALL]
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Then only add `largeTitleEnabled` and `largeTitleDisplayMode` per-window as needed.
|
|
402
|
+
|
|
403
|
+
> **Note:** The official docs only document the `largeTitleEnabled` + `extendEdges` pair for RefreshControl flicker prevention. The full triad for ScrollView content positioning is not in official documentation.
|
|
404
|
+
|
|
405
|
+
See also: [scrolling-views.md](scrolling-views.md) for ScrollView properties and patterns.
|
|
406
|
+
|
|
344
407
|
### Toolbar
|
|
345
408
|
|
|
346
409
|
```javascript
|
|
@@ -241,3 +241,42 @@ scrollView.addEventListener('scroll', (e) => {
|
|
|
241
241
|
4. Consider performance with large datasets
|
|
242
242
|
5. Test on real devices; simulator behavior may differ
|
|
243
243
|
6. Use paging controls for ScrollableView to improve UX
|
|
244
|
+
|
|
245
|
+
## Community-Discovered Patterns
|
|
246
|
+
|
|
247
|
+
### ScrollView inside NavigationWindow with Large Titles (iOS)
|
|
248
|
+
|
|
249
|
+
When placing a ScrollView inside a Window managed by NavigationWindow, configure the Window to ensure proper content positioning — especially when using large titles or translucent bars.
|
|
250
|
+
|
|
251
|
+
Three Window properties must be set together:
|
|
252
|
+
|
|
253
|
+
| Property | Value | Purpose |
|
|
254
|
+
|---|---|---|
|
|
255
|
+
| `extendEdges` | `[Ti.UI.EXTEND_EDGE_ALL]` | Content extends behind bars (enables blur effect) |
|
|
256
|
+
| `autoAdjustScrollViewInsets` | `true` | iOS adjusts ScrollView insets to avoid overlap |
|
|
257
|
+
| `largeTitleEnabled` | `true` | Enables large title that collapses on scroll |
|
|
258
|
+
|
|
259
|
+
Without `autoAdjustScrollViewInsets`, the ScrollView content overlaps behind the navigation bar when `extendEdges` is set. Without `extendEdges`, the large title renders with a visible delay as iOS cannot calculate the full layout upfront.
|
|
260
|
+
|
|
261
|
+
This applies to both standalone NavigationWindow and TabGroup (which wraps each Tab in an implicit NavigationWindow on iOS).
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
const win = Ti.UI.createWindow({
|
|
265
|
+
title: 'Feed',
|
|
266
|
+
largeTitleEnabled: true,
|
|
267
|
+
extendEdges: [Ti.UI.EXTEND_EDGE_ALL],
|
|
268
|
+
autoAdjustScrollViewInsets: true
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const scroll = Ti.UI.createScrollView({
|
|
272
|
+
layout: 'vertical',
|
|
273
|
+
contentWidth: Ti.UI.FILL,
|
|
274
|
+
contentHeight: Ti.UI.SIZE
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Content starts below the nav bar automatically
|
|
278
|
+
scroll.add(Ti.UI.createView({ height: 200, backgroundColor: 'red' }));
|
|
279
|
+
win.add(scroll);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
See [platform-ui-ios.md](platform-ui-ios.md) for the full explanation with `largeTitleDisplayMode` options.
|