@maccesar/titools 5.3.0 → 5.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.
Files changed (98) hide show
  1. package/CONTRIBUTING.md +1 -1
  2. package/README.md +31 -60
  3. package/agents/ti-pro.md +3 -1
  4. package/commands/ti-audit.md +6 -4
  5. package/docs/examples.md +9 -0
  6. package/docs/knowledge-index.md +2 -1
  7. package/lib/config.js +1 -0
  8. package/package.json +1 -1
  9. package/skills/alloy-guides/SKILL.md +18 -179
  10. package/skills/alloy-guides/references/CLI_TASKS.md +17 -216
  11. package/skills/alloy-guides/references/CONCEPTS.md +27 -162
  12. package/skills/alloy-guides/references/CONTROLLERS.md +38 -236
  13. package/skills/alloy-guides/references/MODELS.md +47 -723
  14. package/skills/alloy-guides/references/MODELS_ADVANCED.md +21 -482
  15. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +12 -222
  16. package/skills/alloy-guides/references/VIEWS_STYLES.md +39 -358
  17. package/skills/alloy-guides/references/VIEWS_XML.md +36 -552
  18. package/skills/alloy-guides/references/WIDGETS.md +49 -127
  19. package/skills/alloy-howtos/SKILL.md +14 -169
  20. package/skills/alloy-howtos/references/best_practices.md +9 -113
  21. package/skills/alloy-howtos/references/cli_reference.md +18 -223
  22. package/skills/alloy-howtos/references/config_files.md +50 -133
  23. package/skills/alloy-howtos/references/debugging_troubleshooting.md +19 -63
  24. package/skills/alloy-howtos/references/samples.md +21 -138
  25. package/skills/ti-api/SKILL.md +10 -2
  26. package/skills/ti-api/references/api-android.md +36 -2
  27. package/skills/ti-api/references/api-app-platform.md +39 -3
  28. package/skills/ti-api/references/api-core.md +50 -18
  29. package/skills/ti-api/references/api-data-network.md +49 -35
  30. package/skills/ti-api/references/api-media.md +45 -27
  31. package/skills/ti-api/references/api-services.md +39 -9
  32. package/skills/ti-api/references/api-ui-android.md +33 -13
  33. package/skills/ti-api/references/api-ui-extras.md +41 -15
  34. package/skills/ti-api/references/api-ui-ios-animator.md +42 -26
  35. package/skills/ti-api/references/api-ui-ios.md +74 -2
  36. package/skills/ti-api/references/api-ui-lists.md +32 -16
  37. package/skills/ti-api/references/api-ui-text-input.md +34 -17
  38. package/skills/ti-api/references/api-ui-views.md +27 -1
  39. package/skills/ti-api/references/api-ui-windows-navigation.md +32 -18
  40. package/skills/ti-api/references/api-xml-global.md +66 -16
  41. package/skills/ti-create-release/SKILL.md +98 -0
  42. package/skills/ti-create-release/references/module-discovery.md +69 -0
  43. package/skills/ti-expert/references/adaptive-layouts.md +1 -1
  44. package/skills/ti-guides/SKILL.md +37 -76
  45. package/skills/ti-guides/references/advanced-data-and-images.md +122 -126
  46. package/skills/ti-guides/references/android-manifest.md +24 -83
  47. package/skills/ti-guides/references/app-distribution.md +31 -377
  48. package/skills/ti-guides/references/application-frameworks.md +127 -335
  49. package/skills/ti-guides/references/cli-reference.md +184 -633
  50. package/skills/ti-guides/references/commonjs-advanced.md +81 -231
  51. package/skills/ti-guides/references/compatibility-matrix.md +36 -75
  52. package/skills/ti-guides/references/hello-world.md +95 -70
  53. package/skills/ti-guides/references/hyperloop-native-access.md +52 -448
  54. package/skills/ti-guides/references/resources.md +174 -142
  55. package/skills/ti-guides/references/sdk-release-notes.md +28 -71
  56. package/skills/ti-guides/references/tiapp-config.md +222 -598
  57. package/skills/ti-howtos/SKILL.md +23 -123
  58. package/skills/ti-howtos/references/cross-platform-development.md +119 -324
  59. package/skills/ti-howtos/references/debugging-profiling.md +77 -445
  60. package/skills/ti-howtos/references/extending-titanium.md +199 -673
  61. package/skills/ti-howtos/references/local-data-sources.md +87 -300
  62. package/skills/ti-howtos/references/location-and-maps.md +86 -213
  63. package/skills/ti-howtos/references/media-apis.md +103 -223
  64. package/skills/ti-howtos/references/notification-services.md +86 -506
  65. package/skills/ti-howtos/references/remote-data-sources.md +97 -316
  66. package/skills/ti-howtos/references/using-modules.md +77 -133
  67. package/skills/ti-ui/SKILL.md +28 -143
  68. package/skills/ti-ui/references/icons-and-splash-screens.md +74 -403
  69. package/skills/ti-ui/references/layouts-and-positioning.md +175 -402
  70. package/skills/ti-ui/references/listviews-and-performance.md +100 -703
  71. package/skills/ti-ui/references/platform-conventions.md +180 -0
  72. package/skills/ti-ui/references/user-interface.md +43 -0
  73. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
  74. package/skills/alloy-howtos/references/custom_tags.md +0 -148
  75. package/skills/ti-guides/references/coding-best-practices.md +0 -149
  76. package/skills/ti-guides/references/javascript-primer.md +0 -414
  77. package/skills/ti-guides/references/reserved-words.md +0 -36
  78. package/skills/ti-guides/references/style-and-conventions.md +0 -103
  79. package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -624
  80. package/skills/ti-howtos/references/automation-fastlane-appium.md +0 -96
  81. package/skills/ti-howtos/references/buffer-codec-streams.md +0 -162
  82. package/skills/ti-howtos/references/google-maps-v2.md +0 -172
  83. package/skills/ti-howtos/references/ios-map-kit.md +0 -149
  84. package/skills/ti-howtos/references/ios-platform-deep-dives.md +0 -611
  85. package/skills/ti-howtos/references/tutorials.md +0 -565
  86. package/skills/ti-howtos/references/web-content-integration.md +0 -287
  87. package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -124
  88. package/skills/ti-ui/references/accessibility-deep-dive.md +0 -288
  89. package/skills/ti-ui/references/animation-and-matrices.md +0 -569
  90. package/skills/ti-ui/references/application-structures.md +0 -626
  91. package/skills/ti-ui/references/custom-fonts-styling.md +0 -549
  92. package/skills/ti-ui/references/event-handling.md +0 -401
  93. package/skills/ti-ui/references/gestures.md +0 -448
  94. package/skills/ti-ui/references/orientation.md +0 -374
  95. package/skills/ti-ui/references/platform-ui-android.md +0 -727
  96. package/skills/ti-ui/references/platform-ui-ios.md +0 -576
  97. package/skills/ti-ui/references/scrolling-views.md +0 -288
  98. package/skills/ti-ui/references/tableviews.md +0 -542
@@ -1,576 +0,0 @@
1
- # iOS UI components and conventions
2
-
3
- <!-- TOC-START -->
4
- ## Contents
5
-
6
- - [1. Overview](#1-overview)
7
- - [2. iPad-only UI components](#2-ipad-only-ui-components)
8
- - [3. Badges](#3-badges)
9
- - [4. Settings.bundle integration](#4-settingsbundle-integration)
10
- - [5. Quick Actions and 3D Touch](#5-quick-actions-and-3d-touch)
11
- - [6. Navigation bar (iOS)](#6-navigation-bar-ios)
12
- - [Community-Discovered Patterns](#community-discovered-patterns)
13
- - [7. Tab bar](#7-tab-bar)
14
- - [8. Activity indicator](#8-activity-indicator)
15
- - [9. Platform best practices](#9-platform-best-practices)
16
- - [10. Common issues](#10-common-issues)
17
-
18
- <!-- TOC-END -->
19
-
20
- ## 1. Overview
21
-
22
- iOS has UI components and patterns that differ from Android. This guide covers iPad-only controls, badges, Settings integration, 3D Touch, and iOS navigation patterns.
23
-
24
- ## 2. iPad-only UI components
25
-
26
- ### Popover
27
-
28
- Popovers show temporary content without taking over the whole screen. Use them for menus, options, or detail views.
29
-
30
- ```javascript
31
- const button = Ti.UI.createButton({
32
- title: 'Show popover',
33
- width: 250,
34
- height: 50,
35
- top: 30,
36
- right: 5
37
- });
38
-
39
- const popover = Ti.UI.iPad.createPopover({
40
- width: 300,
41
- height: 250,
42
- title: 'Popover Content',
43
- arrowDirection: Ti.UI.iPad.POPOVER_ARROW_DIRECTION_RIGHT
44
- });
45
-
46
- // Add content to popover
47
- const popoverContent = Ti.UI.createView({
48
- backgroundColor: 'white'
49
- });
50
- popover.add(popoverContent);
51
-
52
- button.addEventListener('click', () => {
53
- popover.show({
54
- view: button, // Anchor to this view
55
- animated: true
56
- });
57
- });
58
-
59
- win.add(button);
60
- ```
61
-
62
- ### Popover events
63
-
64
- ```javascript
65
- popover.addEventListener('hide', () => {
66
- Ti.API.info('Popover hidden');
67
- });
68
-
69
- popover.addEventListener('show', () => {
70
- Ti.API.info('Popover shown');
71
- });
72
-
73
- // Dismiss programmatically
74
- popover.hide();
75
- ```
76
-
77
- ### SplitWindow
78
-
79
- SplitWindow manages a master-detail layout (left list, right detail). It is iPad only.
80
-
81
- ```javascript
82
- // Master (left) window
83
- const masterWin = Ti.UI.createWindow({
84
- backgroundColor: '#fff',
85
- title: 'Master'
86
- });
87
- masterWin.add(Ti.UI.createLabel({
88
- text: 'Master View - Select an item',
89
- font: { fontWeight: 'bold', fontSize: 16 }
90
- }));
91
-
92
- // Detail (right) window
93
- const detailWin = Ti.UI.createWindow({
94
- backgroundColor: '#dfdfdf',
95
- title: 'Detail'
96
- });
97
- detailWin.add(Ti.UI.createLabel({
98
- text: 'Detail View - Item details',
99
- font: { fontWeight: 'bold', fontSize: 16 }
100
- }));
101
-
102
- // Create split window
103
- const splitwin = Ti.UI.iPad.createSplitWindow({
104
- detailView: detailWin,
105
- masterView: masterWin,
106
- orientationModes: [
107
- Ti.UI.LANDSCAPE_LEFT,
108
- Ti.UI.LANDSCAPE_RIGHT
109
- ]
110
- });
111
-
112
- splitwin.open();
113
- ```
114
-
115
- ### SplitWindow in portrait
116
-
117
- By default, the master view is hidden in portrait. To show it:
118
-
119
- ```javascript
120
- splitwin.addEventListener('visible', (e) => {
121
- if (e.view === 'master' && !e.visible) {
122
- // Master is hidden, show it in a popover or navigation
123
- splitwin.showMasterViewInPopover();
124
- }
125
- });
126
- ```
127
-
128
- ## 3. Badges
129
-
130
- ### App icon badge
131
-
132
- ```javascript
133
- // Set badge to number
134
- Ti.UI.iOS.appBadge = 23;
135
-
136
- // Remove badge (set to null, not 0)
137
- Ti.UI.iOS.appBadge = null;
138
-
139
- // Note: Setting to 0 still displays "0"
140
- ```
141
-
142
- ### Tab badge
143
-
144
- ```javascript
145
- const tabGroup = Ti.UI.createTabGroup();
146
-
147
- const win1 = Ti.UI.createWindow({ title: 'Window 1' });
148
-
149
- const tab1 = Ti.UI.createTab({
150
- icon: 'myIcon.png',
151
- title: 'Tab 1',
152
- window: win1,
153
- badge: 10 // Show badge with number
154
- });
155
-
156
- // Update badge
157
- tab1.setBadge(5);
158
- tab1.badge = 5;
159
-
160
- // Clear badge
161
- tab1.setBadge(null);
162
- tab1.badge = null;
163
- ```
164
-
165
- ## 4. Settings.bundle integration
166
-
167
- iOS apps can expose user settings in the Settings app using a Settings.bundle.
168
-
169
- Setup:
170
- - Place the bundle at `platform/iphone/Settings.bundle/` (SDK 1.8+)
171
- - The bundle contains `Root.plist`, which defines the settings UI (toggles, text fields, groups, etc.)
172
- - Edit `Root.plist` using Xcode's Property List editor for a visual interface
173
-
174
- Key conventions: Settings keys typically use the `_preference` suffix, for example `username_preference` or `enabled_preference`.
175
-
176
- ### Access preferences in the app
177
-
178
- ```javascript
179
- // Read a preference set in iOS Settings app
180
- const username = Ti.App.Properties.getString('username_preference');
181
-
182
- // Must match the "Key" value from Root.plist
183
- const name = Ti.App.Properties.getString('name_preference');
184
- const enabled = Ti.App.Properties.getBool('enabled_preference');
185
- ```
186
-
187
- ## 5. Quick Actions and 3D Touch
188
-
189
- ### Static Quick Actions (via tiapp.xml)
190
-
191
- Static shortcuts are defined in `tiapp.xml` and available immediately after install.
192
-
193
- - Required keys: `UIApplicationShortcutItemTitle`, `UIApplicationShortcutItemType`
194
- - Optional keys: `UIApplicationShortcutItemSubtitle`, `UIApplicationShortcutItemIconType`, `UIApplicationShortcutItemIconFile`, `UIApplicationShortcutItemUserInfo`
195
-
196
- ```xml
197
- <ios>
198
- <plist>
199
- <dict>
200
- <key>UIApplicationShortcutItems</key>
201
- <array>
202
- <dict>
203
- <key>UIApplicationShortcutItemTitle</key>
204
- <string>New Message</string>
205
- <key>UIApplicationShortcutItemType</key>
206
- <string>com.app.newmessage</string>
207
- <key>UIApplicationShortcutItemIconType</key>
208
- <string>UIApplicationShortcutIconTypeCompose</string>
209
- </dict>
210
- </array>
211
- </dict>
212
- </plist>
213
- </ios>
214
- ```
215
-
216
- Quick action titles and subtitles can be localized using `i18n/LANG/app.xml` (not `strings.xml`). Use the localized key as the value in `tiapp.xml`.
217
-
218
- To use custom images for quick action icons, enable app thinning in `tiapp.xml` with `<use-app-thinning>true</use-app-thinning>` inside the `<ios>` element.
219
-
220
- ### Dynamic Quick Actions
221
-
222
- ```javascript
223
- if (Ti.UI.iOS.forceTouchSupported) {
224
- const appShortcuts = Ti.UI.iOS.createApplicationShortcuts();
225
-
226
- appShortcuts.addDynamicShortcut({
227
- itemtype: 'com.myapp.share',
228
- title: 'Share Photo',
229
- subtitle: 'Share last photo',
230
- icon: Ti.UI.iOS.SHORTCUT_ICON_TYPE_SHARE,
231
- userInfo: {
232
- action: 'share_photo',
233
- photoId: '123'
234
- }
235
- });
236
-
237
- // Remove specific shortcut
238
- appShortcuts.removeDynamicShortcut('com.myapp.share');
239
-
240
- // Remove all dynamic shortcuts
241
- appShortcuts.removeAllDynamicShortcuts();
242
- }
243
- ```
244
-
245
- ### Handle quick actions
246
-
247
- ```javascript
248
- Ti.App.iOS.addEventListener('shortcutitemclick', (e) => {
249
- Ti.API.info(`Shortcut clicked: ${e.itemtype}`);
250
-
251
- switch (e.itemtype) {
252
- case 'com.myapp.add':
253
- addNewItem();
254
- break;
255
- case 'com.myapp.recent':
256
- openRecent();
257
- break;
258
- case 'com.myapp.share':
259
- sharePhoto(e.userInfo.photoId);
260
- break;
261
- }
262
- });
263
- ```
264
-
265
- ### Peek and pop
266
-
267
- Peek shows a preview, Pop opens the full view.
268
-
269
- #### Enable peek and pop
270
-
271
- ```javascript
272
- if (Ti.UI.iOS.forceTouchSupported) {
273
-
274
- const preview = Alloy.createController('preview').getView();
275
- const detail = Alloy.createController('detail').getView();
276
-
277
- const shareAction = Ti.UI.iOS.createPreviewAction({
278
- title: 'Share',
279
- style: Ti.UI.iOS.PREVIEW_ACTION_STYLE_DEFAULT
280
- });
281
-
282
- shareAction.addEventListener('click', () => {
283
- // Handle share action
284
- });
285
-
286
- const previewContext = Ti.UI.iOS.createPreviewContext({
287
- preview: preview,
288
- contentHeight: 400,
289
- actions: [shareAction]
290
- });
291
-
292
- previewContext.addEventListener('peek', () => {
293
- Ti.API.info('User started peeking');
294
- });
295
-
296
- previewContext.addEventListener('pop', () => {
297
- Ti.API.info('User popped to full view');
298
- detail.open();
299
- });
300
-
301
- // Attach to view
302
- $.peekView.previewContext = previewContext;
303
- }
304
- ```
305
-
306
- #### Preview action styles
307
-
308
- ```javascript
309
- Ti.UI.iOS.PREVIEW_ACTION_STYLE_DEFAULT
310
- Ti.UI.iOS.PREVIEW_ACTION_STYLE_SELECTED // Blue background
311
- Ti.UI.iOS.PREVIEW_ACTION_STYLE_DESTRUCTIVE // Red background
312
- ```
313
-
314
- #### Peek and pop details
315
-
316
- - Use `contentHeight` on the preview context to control preview height (for example `contentHeight: 400`).
317
- - Use `Ti.UI.iOS.createPreviewActionGroup()` to group related preview actions into a submenu:
318
-
319
- ```javascript
320
- const subAction1 = Ti.UI.iOS.createPreviewAction({ title: 'Copy', style: Ti.UI.iOS.PREVIEW_ACTION_STYLE_DEFAULT });
321
- const subAction2 = Ti.UI.iOS.createPreviewAction({ title: 'Move', style: Ti.UI.iOS.PREVIEW_ACTION_STYLE_DEFAULT });
322
-
323
- const actionGroup = Ti.UI.iOS.createPreviewActionGroup({
324
- title: 'Organize',
325
- style: Ti.UI.iOS.PREVIEW_ACTION_STYLE_DEFAULT,
326
- actions: [subAction1, subAction2]
327
- });
328
- ```
329
-
330
- Important: 3D Touch features (peek and pop, quick actions with force) can only be tested on physical devices with 3D Touch hardware. The iOS Simulator does not support force touch.
331
-
332
- ## 6. Navigation bar (iOS)
333
-
334
- ### NavigationWindow
335
-
336
- ```javascript
337
- const win1 = Ti.UI.createWindow({
338
- backgroundColor: 'white',
339
- title: 'First Window'
340
- });
341
-
342
- const navWindow = Ti.UI.createNavigationWindow({
343
- window: win1
344
- });
345
-
346
- // Open second window
347
- const win2 = Ti.UI.createWindow({
348
- backgroundColor: 'gray',
349
- title: 'Second Window'
350
- });
351
-
352
- navWindow.openWindow(win2, { animated: true });
353
-
354
- // Close to go back
355
- win2.close();
356
-
357
- // Hide navigation bar
358
- win1.navBarHidden = true;
359
- ```
360
-
361
- ## Community-Discovered Patterns
362
-
363
- ### Large Titles + ScrollView: required property triad (iOS)
364
-
365
- 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.
366
-
367
- ```javascript
368
- const win = Ti.UI.createWindow({
369
- title: 'My Screen',
370
- largeTitleEnabled: true,
371
- largeTitleDisplayMode: Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_AUTOMATIC,
372
- extendEdges: [Ti.UI.EXTEND_EDGE_ALL],
373
- autoAdjustScrollViewInsets: true,
374
- barColor: '#1e293b',
375
- backgroundColor: '#0f172a'
376
- });
377
-
378
- const scrollView = Ti.UI.createScrollView({
379
- layout: 'vertical',
380
- contentWidth: Ti.UI.FILL,
381
- contentHeight: Ti.UI.SIZE
382
- });
383
-
384
- scrollView.add(Ti.UI.createLabel({ text: 'Content here' }));
385
- win.add(scrollView);
386
- navWindow.openWindow(win);
387
- ```
388
-
389
- | Property | Purpose | What breaks without it |
390
- |---|---|---|
391
- | `largeTitleEnabled: true` | Large title that collapses on scroll | No large title behavior |
392
- | `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) |
393
- | `autoAdjustScrollViewInsets: true` | Automatically adjusts ScrollView insets | Content overlaps behind the nav bar |
394
-
395
- > **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.
396
-
397
- `largeTitleDisplayMode` controls collapse behavior:
398
- - `LARGE_TITLE_DISPLAY_MODE_AUTOMATIC` (default) — inherits from previous window; collapses on scroll
399
- - `LARGE_TITLE_DISPLAY_MODE_ALWAYS` — title stays large regardless of scroll position
400
- - `LARGE_TITLE_DISPLAY_MODE_NEVER` — always standard title size
401
-
402
- #### Works with both NavigationWindow and TabGroup
403
-
404
- 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`.
405
-
406
- #### Recommended: global defaults
407
-
408
- Instead of repeating the properties on every Window, set them as global defaults:
409
-
410
- ```javascript
411
- // app.tss (Alloy)
412
- 'Window[platform=ios]': {
413
- autoAdjustScrollViewInsets: true,
414
- extendEdges: [Ti.UI.EXTEND_EDGE_ALL]
415
- }
416
- ```
417
-
418
- Then only add `largeTitleEnabled` and `largeTitleDisplayMode` per-window as needed.
419
-
420
- > **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.
421
-
422
- See also: [scrolling-views.md](scrolling-views.md) for ScrollView properties and patterns.
423
-
424
- ### Toolbar
425
-
426
- ```javascript
427
- const flexSpace = Ti.UI.createButton({
428
- systemButton: Ti.UI.iOS.SystemButton.FLEXIBLE_SPACE
429
- });
430
-
431
- const refreshButton = Ti.UI.createButton({
432
- title: 'Refresh'
433
- });
434
-
435
- const toolbar = Ti.UI.createToolbar({
436
- items: [refreshButton, flexSpace],
437
- bottom: 0
438
- });
439
-
440
- win.add(toolbar);
441
- ```
442
-
443
- ### System buttons
444
-
445
- ```javascript
446
- Ti.UI.iOS.SystemButton.DONE
447
- Ti.UI.iOS.SystemButton.CANCEL
448
- Ti.UI.iOS.SystemButton.EDIT
449
- Ti.UI.iOS.SystemButton.SAVE
450
- Ti.UI.iOS.SystemButton.ADD
451
- Ti.UI.iOS.SystemButton.FLEXIBLE_SPACE
452
- Ti.UI.iOS.SystemButton.FIXED_SPACE
453
- // ... and more
454
- ```
455
-
456
- ## 7. Tab bar
457
-
458
- ### Create a tab bar
459
-
460
- ```javascript
461
- const tabGroup = Ti.UI.createTabGroup();
462
-
463
- const tab1 = Ti.UI.createTab({
464
- icon: 'home.png',
465
- title: 'Home',
466
- window: Ti.UI.createWindow({ backgroundColor: 'white' })
467
- });
468
-
469
- const tab2 = Ti.UI.createTab({
470
- icon: 'settings.png',
471
- title: 'Settings',
472
- window: Ti.UI.createWindow({ backgroundColor: 'gray' })
473
- });
474
-
475
- tabGroup.addTab(tab1);
476
- tabGroup.addTab(tab2);
477
-
478
- tabGroup.open();
479
- ```
480
-
481
- ### Tab bar customization (iOS)
482
-
483
- ```javascript
484
- tabGroup.setActiveTabIconColor('blue');
485
- tabGroup.setActiveTabColor('#f0f0f0');
486
-
487
- // Hide tab bar on specific window
488
- win1.tabBarHidden = true;
489
-
490
- // Set tab bar style (deprecated in iOS 13+)
491
- tabGroup.tabsStyle = Ti.UI.iOS.TABS_STYLE_BOTTOM;
492
- ```
493
-
494
- ## 8. Activity indicator
495
-
496
- ```javascript
497
- const activityIndicator = Ti.UI.createActivityIndicator({
498
- message: 'Loading...',
499
- color: 'white',
500
- backgroundColor: '#333',
501
- font: { fontSize: 16, fontWeight: 'bold' }
502
- });
503
-
504
- activityIndicator.show();
505
-
506
- // Later
507
- activityIndicator.hide();
508
- ```
509
-
510
- ### iOS-specific location
511
-
512
- ```javascript
513
- const activityIndicator = Ti.UI.createActivityIndicator({
514
- message: 'Loading...',
515
- location: Ti.UI.iOS.ACTIVITY_INDICATOR_DIALOG,
516
- opacity: 0.8
517
- });
518
- ```
519
-
520
- ## 9. Platform best practices
521
-
522
- ### Follow iOS Human Interface Guidelines
523
-
524
- - Use NavigationWindow for hierarchical navigation
525
- - Use Tab Bar for top-level categories
526
- - Present modal views for focused tasks
527
- - Use Popovers for auxiliary content (iPad)
528
- - Respect 3D Touch conventions
529
-
530
- ### iOS-specific patterns
531
-
532
- ```javascript
533
- // Use system buttons for standard actions
534
- const doneButton = Ti.UI.createButton({
535
- systemButton: Ti.UI.iOS.SystemButton.DONE
536
- });
537
-
538
- // Use NavigationWindow animations
539
- navWindow.openWindow(win2, {
540
- animated: true,
541
- transition: Ti.UI.iOS.NavigationWindowTransitionStyle.NONE
542
- });
543
-
544
- // Respect safe area (iPhone X+)
545
- const view = Ti.UI.createView({
546
- top: Ti.Platform.displayCaps.platformHeight > 800 ? 44 : 20 // Account for notch
547
- });
548
- ```
549
-
550
- ## 10. Common issues
551
-
552
- ### Settings not appearing
553
-
554
- Problem: Settings are not visible in the Settings app.
555
-
556
- Solutions:
557
- 1. Clean and rebuild the project
558
- 2. Check plist syntax
559
- 3. Ensure Settings.bundle is in `platform/iphone/`
560
- 4. Kill and relaunch the Settings app
561
-
562
- ### 3D Touch not working
563
-
564
- Problem: 3D Touch features do not respond.
565
-
566
- Solutions:
567
- 1. Test on a physical device with 3D Touch hardware
568
- 2. Check `Ti.UI.iOS.forceTouchSupported` before using
569
- 3. Ensure iOS 9 or later
570
- 4. Verify `previewContext` is properly attached
571
-
572
- ### SplitWindow issues
573
-
574
- Problem: Master view is not visible in portrait.
575
-
576
- Solution: This is default behavior. Use `showMasterViewInPopover()` or handle it via NavigationWindow.