Mixing FireMonkey controls and TMS iCL controls

In this article we try to give a technical background of the differences between FireMonkey framework controls and TMS iCL controls. With this background it should be easier to understand the limitations and pitfalls with mixing FireMonkey framework controls and TMS iCL controls.

FireMonkey controls

In a FireMonkey mobile applications, a FireMonkey control is a class that will paint its visuals via iOS Quartz on a bitmap. That bitmap is in turn bitblitted on the screen. The FireMonkey form manages keyboard & touch input centrally. As such, FireMonkey form code is responsible for delegating key & mouse input itself to the control that has focus. The FireMonkey control is responsible itself for things such as a different painting for the control in focused state, painting the caret, painting keys entered etc.. The easiest way to look at it as classic VCL developer is to consider FireMonkey controls as classes that descend from TGraphicControl with a VCL TForm that will still treat such controls as optionally focusable and that will delegate these keys to the focused control. The TGraphicControl is then fully responsible for handling this.

TMS iCL controls

TMS iCL controls expose the different iOS views/controllers as classes. The iOS UITextField view is the iOS operating system control that handles basic text editing for example. Here, it is the operating system itself that will handle the painting of the control, that will handle directly keyboard interaction and touch. These iOS controls descend from UIView and the easiest is to consider these controls as equivalents of TCustomControl descendents in the VCL framework.

Interaction between FireMonkey controls and TMS iCL controls

With this knowledge in mind, it becomes easier to understand the limitations and pitfalls with mixing FireMonkey controls and TMS iCL controls. The good news is that even with these limitations there are still many useful scenarios left for combining both control types in the same form. If we look at FireMonkey controls as TGraphicControl descendents in the VCL world and TMS iCL controls as TCustomControl descendents, it is easy to understand that a TMS iCL control will always be displayed on top of a FireMonkey control. The FireMonkey control has no notion of control parent/child (or in iOS terminology view/subview) relationship at operating system level. Its parent/child relationship is limited to the 'artificial' level of the FireMonkey canvas where controls are painted. Just like when you drop a TPaintBox on top of a TEdit in a VCL Windows applications, the TEdit will show through the TPaintBox. This is of course because the TPaintBox doesn't really exist in Windows, it is just painted directly on the form. The same will happen when you drop a FireMonkey TPanel on top of a TTMSFMXNativeUITextField. Another consequence is that when you drop a TTMSFMXNativeUITextField on a FireMonkey TPageControl, the TTMSFMXNativeUITextField will always show, irrespective of the active page of the TPageControl. Again, this is because the TPageControl is nothing more than something painted on the form without a real parent/child relationship, i.e. view/subview relationship to native iOS operating system controls that TMS iCL exposes. This means that when you want to use a TMS iCL control on a FireMonkey TPageControl, you'll need to deal with setting the visibility of the native iCL control at application level. The reverse is also true, i.e. when you have a native iOS control like a TTMSFMXNativeUIScrollView, it won't work to insert a FireMonkey framework control in this TTMSFMXNativeUIScrollView. All the FireMonkey control does is paint itself via a bitmap on the form and as such, the TTMSFMXNativeUIScrollView will always overlap it.

Rule of thumb

For experienced VCL developers, by far the easiest way to proactively deal with this distinction between FireMonkey framework controls and TMS iCL controls is to think of them as TGraphicControl descendents versus TCustomControl descendents. Just like in Windows, TGraphicControl isn't appropriate for everything you want to do, consider also to use the proper iOS control equivalent, i.e. use a TTMSFMXNativeUITabBarController instead of a TPageControl when you want to perform paging between native iOS TMS iCL controls.