Skip to content

Instantly share code, notes, and snippets.

@hshristov
Last active April 4, 2018 14:25
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save hshristov/f26f9a4db66d10aa99430c978e5411da to your computer and use it in GitHub Desktop.
Save hshristov/f26f9a4db66d10aa99430c978e5411da to your computer and use it in GitHub Desktop.

One of the main goals of tns-core-modules@4.0 is to enable more flexible composition of UI. Let's start with some history. Before 4.0 we create Frame control for you (check application.ios.ts and frame.android.ts). Frame control allows you to do navigation forward or backward. While this is convenient it introduce other issues that can't be workaround easliy. For example if you want to have TabView in all pages you have to include it in the xml and set its selectedIndex so that once you navigate to different page a correct TabViewItem is selected. This leads to several problems:

  • parse more xml
  • increase memory usage
  • increase loading time

Same issues apply if you want to have SideDrawer control as a root component.

So in order to resolve these starting with 4.0 application class have new method: run() When using run we will no longer create Frame instance (start method still do). Keep in mind that start is marked as deprecated.

How to migrate existing apps:

  • If you don't want to use the new functionality don't do anything but keep in mind that at some point start method could be removed. Consider migrating to run method.

If you want to migrate your app here are the steps:

  • call application.run() instead of application.start(). Both methods accepts the same arguments.

There are few cases from here:

  • If you want to simulate the behavior before 4.0 you wrap the page element in Frame element like:
<Frame src="mainpage">
	<Page>
		<!-- page content goes here -->
	</Page>
</Frame>

This API is not final yet. There is discussion if we should remove the ability to nest Page inside Frame and instead add src property on Frame component.

  • as run() doesn't create anything behind the scene you can now create root TabView like this:
main.xml
<TabView>
	<TabViewItem title="Item with navigation">
		<Frame>
			<Page>
				<!-- page content goes here -->
			</Page>
		</Frame>
	</TabViewItem>
	<TabViewItem title="Item without navigation">
		<GridLayout>
			<!-- content here -->
		</GridLayout>
	</TabViewItem>
</TabView>
  • or a root SideDrawer like this:
<SideDrawer>
	<TabView>
		<TabViewItem title="Item with navigation">
			<Frame>
				<Page>
					<!-- page content goes here -->
				</Page>
			</Frame>
		</TabViewItem>
		<TabViewItem title="Item without navigation">
			<GridLayout>
				<!-- content here -->
			</GridLayout>
		</TabViewItem>
	</TabView>
</SideDrawer>

The other major feature is that we can now show almost anything as modal dialog. showModal method is moved from Page to View component and there is no limitation to have Page as root element when showing something as modal view. For example you can show as modal some xml which contains Frame or TabView as root element. The above main.xml can be sgown as modal view.

In order to allow such nesting we fallback to iOS layout system which have some side effects on few of our components. Instead of manually laying out Frame, Page and TabView we leave iOS to position them and after that we run a layout pass over our components using the size that iOS gave us. This reduce the layout passes and fixes a lot of glitches with jumpy actionbar and page transitions. The only drawback is that we no longer apply width, height, margins & alignments on Page, Frame and TabView. As they are fullscreen in most apps this shouldn't be such a major problem.

Few other important changes

With the iPhone X Apple released new design guidelines that says background must be fullscreen while content to stay in the safe area. We have implemented this using UILayoutGuide which is a iOS 9 feature so modules 4.0 will require at least iOS 9. We also let Frame, Page and TabView to be fullscreen so that background is fullscreen too but place content inside the safe area depending on the content type - if content is UIScrollView or its descendent it knows how to handle navigationBar as well as TabBar so we give it full size. Otherwize we give safe area size (more or less depending on some native iOS properties). This leads to the much desired effect where ListView will scroll under ActionBar and TabView.

The full list of changes are described in the PR

@tobydeh
Copy link

tobydeh commented Jan 25, 2018

Awesome work, thank you!

@jogboms
Copy link

jogboms commented Jan 25, 2018

Yaassss!!! Been waiting on this!!! 👍

@jeremypele
Copy link

🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment