|
627 | 627 | </span> |
628 | 628 | </a> |
629 | 629 |
|
| 630 | +</li> |
| 631 | + |
| 632 | + <li class="md-nav__item"> |
| 633 | + <a href="#platform-specifics" class="md-nav__link"> |
| 634 | + <span class="md-ellipsis"> |
| 635 | + Platform specifics |
| 636 | + </span> |
| 637 | + </a> |
| 638 | + |
| 639 | + <nav class="md-nav" aria-label="Platform specifics"> |
| 640 | + <ul class="md-nav__list"> |
| 641 | + |
| 642 | + <li class="md-nav__item"> |
| 643 | + <a href="#ios-uiviewcontroller-per-page" class="md-nav__link"> |
| 644 | + <span class="md-ellipsis"> |
| 645 | + iOS (UIViewController per page) |
| 646 | + </span> |
| 647 | + </a> |
| 648 | + |
| 649 | +</li> |
| 650 | + |
| 651 | + <li class="md-nav__item"> |
| 652 | + <a href="#android-single-activity-fragment-stack" class="md-nav__link"> |
| 653 | + <span class="md-ellipsis"> |
| 654 | + Android (single Activity, Fragment stack) |
| 655 | + </span> |
| 656 | + </a> |
| 657 | + |
| 658 | +</li> |
| 659 | + |
| 660 | + </ul> |
| 661 | + </nav> |
| 662 | + |
| 663 | +</li> |
| 664 | + |
| 665 | + <li class="md-nav__item"> |
| 666 | + <a href="#comparison-to-other-frameworks" class="md-nav__link"> |
| 667 | + <span class="md-ellipsis"> |
| 668 | + Comparison to other frameworks |
| 669 | + </span> |
| 670 | + </a> |
| 671 | + |
630 | 672 | </li> |
631 | 673 |
|
632 | 674 | </ul> |
|
865 | 907 | </span> |
866 | 908 | </a> |
867 | 909 |
|
| 910 | +</li> |
| 911 | + |
| 912 | + <li class="md-nav__item"> |
| 913 | + <a href="#platform-specifics" class="md-nav__link"> |
| 914 | + <span class="md-ellipsis"> |
| 915 | + Platform specifics |
| 916 | + </span> |
| 917 | + </a> |
| 918 | + |
| 919 | + <nav class="md-nav" aria-label="Platform specifics"> |
| 920 | + <ul class="md-nav__list"> |
| 921 | + |
| 922 | + <li class="md-nav__item"> |
| 923 | + <a href="#ios-uiviewcontroller-per-page" class="md-nav__link"> |
| 924 | + <span class="md-ellipsis"> |
| 925 | + iOS (UIViewController per page) |
| 926 | + </span> |
| 927 | + </a> |
| 928 | + |
| 929 | +</li> |
| 930 | + |
| 931 | + <li class="md-nav__item"> |
| 932 | + <a href="#android-single-activity-fragment-stack" class="md-nav__link"> |
| 933 | + <span class="md-ellipsis"> |
| 934 | + Android (single Activity, Fragment stack) |
| 935 | + </span> |
| 936 | + </a> |
| 937 | + |
| 938 | +</li> |
| 939 | + |
| 940 | + </ul> |
| 941 | + </nav> |
| 942 | + |
| 943 | +</li> |
| 944 | + |
| 945 | + <li class="md-nav__item"> |
| 946 | + <a href="#comparison-to-other-frameworks" class="md-nav__link"> |
| 947 | + <span class="md-ellipsis"> |
| 948 | + Comparison to other frameworks |
| 949 | + </span> |
| 950 | + </a> |
| 951 | + |
868 | 952 | </li> |
869 | 953 |
|
870 | 954 | </ul> |
@@ -927,12 +1011,51 @@ <h2 id="lifecycle">Lifecycle<a class="headerlink" href="#lifecycle" title="Perma |
927 | 1011 | <li><code>on_save_instance_state</code></li> |
928 | 1012 | <li><code>on_restore_instance_state</code></li> |
929 | 1013 | </ul> |
930 | | -<p>Android forwards Activity lifecycle via the template <code>MainActivity</code> and <code>PageActivity</code>. iOS forwards <code>viewWillAppear</code>/<code>viewWillDisappear</code> via an internal registry.</p> |
| 1014 | +<p>Android uses a single <code>MainActivity</code> hosting a <code>NavHostFragment</code> and a generic <code>PageFragment</code> per page. iOS forwards <code>viewWillAppear</code>/<code>viewWillDisappear</code> via an internal registry.</p> |
931 | 1015 | <h2 id="notes">Notes<a class="headerlink" href="#notes" title="Permanent link">¶</a></h2> |
932 | 1016 | <ul> |
933 | | -<li>On Android, <code>push</code> launches a template <code>PageActivity</code> and passes <code>PY_PAGE_PATH</code> and optional JSON args.</li> |
| 1017 | +<li>On Android, <code>push</code> navigates via <code>NavController</code> to a <code>PageFragment</code> and passes <code>page_path</code> and optional JSON <code>args</code>.</li> |
934 | 1018 | <li>On iOS, <code>push</code> uses the root <code>UINavigationController</code> to push a new <code>ViewController</code> and passes page info via KVC.</li> |
935 | 1019 | </ul> |
| 1020 | +<h2 id="platform-specifics">Platform specifics<a class="headerlink" href="#platform-specifics" title="Permanent link">¶</a></h2> |
| 1021 | +<h3 id="ios-uiviewcontroller-per-page">iOS (UIViewController per page)<a class="headerlink" href="#ios-uiviewcontroller-per-page" title="Permanent link">¶</a></h3> |
| 1022 | +<ul> |
| 1023 | +<li>Each PythonNative page is hosted by a Swift <code>ViewController</code> instance.</li> |
| 1024 | +<li>Pages are pushed and popped on a root <code>UINavigationController</code>.</li> |
| 1025 | +<li>Lifecycle is forwarded from Swift to the registered Python page instance.</li> |
| 1026 | +<li>Root view wiring: <code>Page.set_root_view</code> sizes and inserts the Python-native view into the controller’s view.</li> |
| 1027 | +</ul> |
| 1028 | +<p>Why this matches iOS conventions |
| 1029 | +- iOS apps commonly model screens as <code>UIViewController</code>s and use <code>UINavigationController</code> for hierarchical navigation. |
| 1030 | +- The approach integrates cleanly with add-to-app and system behaviors (e.g., state restoration).</p> |
| 1031 | +<h3 id="android-single-activity-fragment-stack">Android (single Activity, Fragment stack)<a class="headerlink" href="#android-single-activity-fragment-stack" title="Permanent link">¶</a></h3> |
| 1032 | +<ul> |
| 1033 | +<li>Single host <code>MainActivity</code> sets a <code>NavHostFragment</code> containing a navigation graph.</li> |
| 1034 | +<li>Each PythonNative page is represented by a generic <code>PageFragment</code> which instantiates the Python page and attaches its root view.</li> |
| 1035 | +<li><code>push</code>/<code>pop</code> delegate to <code>NavController</code> (via a small <code>Navigator</code> helper).</li> |
| 1036 | +<li>Arguments (<code>page_path</code>, <code>args_json</code>) live in Fragment arguments and restore across configuration changes and process death.</li> |
| 1037 | +</ul> |
| 1038 | +<p>Why this matches Android conventions |
| 1039 | +- Modern Android apps favor one Activity with many Fragments, using Jetpack Navigation for back stack, transitions, and deep links. |
| 1040 | +- It simplifies lifecycle, back handling, and state compared to one-Activity-per-screen.</p> |
| 1041 | +<h2 id="comparison-to-other-frameworks">Comparison to other frameworks<a class="headerlink" href="#comparison-to-other-frameworks" title="Permanent link">¶</a></h2> |
| 1042 | +<ul> |
| 1043 | +<li>React Native</li> |
| 1044 | +<li>Android: single <code>Activity</code>, screens managed via <code>Fragment</code>s (e.g., <code>react-native-screens</code>).</li> |
| 1045 | +<li>iOS: screens map to <code>UIViewController</code>s pushed on <code>UINavigationController</code>.</li> |
| 1046 | +<li>.NET MAUI / Xamarin.Forms</li> |
| 1047 | +<li>Android: single <code>Activity</code>, pages via Fragments/Navigation.</li> |
| 1048 | +<li>iOS: pages map to <code>UIViewController</code>s on a <code>UINavigationController</code>.</li> |
| 1049 | +<li>NativeScript</li> |
| 1050 | +<li>Android: single <code>Activity</code>, pages as <code>Fragment</code>s.</li> |
| 1051 | +<li>iOS: pages as <code>UIViewController</code>s on <code>UINavigationController</code>.</li> |
| 1052 | +<li>Flutter (special case)</li> |
| 1053 | +<li>Android: single <code>Activity</code> (<code>FlutterActivity</code>/<code>FlutterFragmentActivity</code>).</li> |
| 1054 | +<li>iOS: <code>FlutterViewController</code> hosts Flutter’s internal navigator; add-to-app can push multiple <code>FlutterViewController</code>s.</li> |
| 1055 | +</ul> |
| 1056 | +<p>Bottom line |
| 1057 | +- iOS: one host VC class, many instances on a <code>UINavigationController</code>. |
| 1058 | +- Android: one host <code>Activity</code>, many <code>Fragment</code>s with Jetpack Navigation.</p> |
936 | 1059 |
|
937 | 1060 |
|
938 | 1061 |
|
|
0 commit comments