Mastering Dark Mode in ROMA: A Complete Guide to Cross‑Platform Theme Adaptation

This article explains how the ROMA cross‑platform framework implements dark mode, covering configuration options, theme‑mode attributes, color mapping, iOS trait handling, and practical code examples for seamless UI theme switching.

JD Tech Talk
JD Tech Talk
JD Tech Talk
Mastering Dark Mode in ROMA: A Complete Guide to Cross‑Platform Theme Adaptation

Background

Dark mode reduces blue light in low‑light environments, eases eye fatigue, improves contrast and readability, and saves battery life. JD Finance App supports dark mode from version 8.0.20, and the ROMA framework fully supports dark‑mode settings. This article details the ROMA adaptation process.

ROMA Configuration and Usage

The app offers three dark‑mode options: force light, force dark, and follow system. Switching to dark mode does not recreate the view hierarchy, resulting in a smooth transition.

Image
Image

1. View Display Mode Setting

ROMA provides a theme-mode attribute for all tags and pages, indicating the current display mode. Three modes are available:

1 – force light mode

2 – force dark mode

3 – follow mode (inherit from parent or system)

Example:

<template theme-mode=3>
  <div style="align-self: stretch; height: 100px; margin: 10px;" theme-mode="1">
    <text style="color:#000000; font-size: 12px;">Text test</text>
  </div>
</template>

Setting theme-mode on a node lets business flexibly customize the display mode for the whole view or individual elements.

Image
Image

2. View Color Setting

Ideally, business can adapt to dark mode without code changes by using a complete color‑mapping table (e.g., colorcolor-dark) and designing UI according to that table.

Image
Image

For more complex scenarios ROMA offers xxx-dark style properties, such as background-color-dark, color-dark, and src-dark:

<div style="background-color: white; background-color-dark: '#EF4034';">
  <text style="color: '#666666'; color-dark:'#F9F9F9';">Text test</text>
  <img src="https://img0.baidu.com/it/u=3838093562,4126749835&fm=253&fmt=auto&app=138&f=JPEG?w=1144&h=500" src-dark="https://imgs.699pic.com/images/500/465/562.jpg!list1x.v2">
</div>

View Mode Switching Principle Analysis

ROMA simplifies dark‑mode adaptation with simple configuration, but the underlying process involves the entire view hierarchy. The iOS example illustrates how trait changes propagate.

1. UITraitEnvironment Protocol Details

UITraitEnvironment is a fundamental iOS protocol implemented by views and view controllers to monitor interface trait changes such as dark/light mode, device rotation, or size class changes.

@protocol UITraitEnvironment <NSObject>
@property (nonatomic, readonly) UITraitCollection *traitCollection API_AVAILABLE(ios(8.0));
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_DEPRECATED("Use the trait change registration APIs declared in the UITraitChangeObservable protocol", ios(8.0, 17.0), visionos(1.0, 1.0)) API_UNAVAILABLE(watchos);
@end

From iOS 17 onward, UITraitChangeObservable is recommended for finer‑grained monitoring.

API_AVAILABLE(ios(17.0), tvos(17.0)) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
@protocol UITraitChangeObservable
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withHandler:(UITraitChangeHandler)handler;
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withTarget:(id)target action:(SEL)action;
- (id<UITraitChangeRegistration>)registerForTraitChanges:(NSArray<UITrait> *)traits withAction:(SEL)action;
- (void)unregisterForTraitChanges:(id<UITraitChangeRegistration>)registration;
@end

2. Impact of System Trait Changes on View Hierarchy

The trait collection propagates from top to bottom:

System traits are provided by

UIScreen
UIWindow

inherits traits from UIScreen Root view controller inherits from UIWindow Child view controllers inherit from their parent controllers

Views inherit traits from their view controller

Subviews inherit traits from their parent view

Layer objects listen to the corresponding view’s traits to adjust themselves

Image
Image

3. Setting View Colors Dynamically

Direct color properties (e.g., textColor, backgroundColor) can be set with UIColor dynamic providers so that the appropriate color is automatically used when the interface style changes.

UIColor *dycolor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
    if ([traitCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
        return lightResolvedColor;
    } else {
        return darkResolvedColor ? darkResolvedColor : (lightResolvedColor ? lightResolvedColor : [UIColor clearColor]);
    }
}];
view.backgroundColor = dycolor;

4. Other View Settings

For layer colors, image resources, Lottie assets, etc., register a theme‑change callback on the view and adjust the layer properties when the mode changes.

UIColor *borderColor = jr_themeColorForTrans(_bordercolor_light, _bordercolor_dark);
CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
__weak CAShapeLayer *weakBorderLayer = borderLayer;
[self.view jr_registerForJRThemeChangesWithHandler:^(JRThemeModeStyle style) {
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    weakBorderLayer.strokeColor = borderColor.CGColor;
    [CATransaction commit];
} key:@"jr_trans_layer_border_color_key"];

Conclusion

ROMA, as a modern cross‑platform framework, treats dark‑mode adaptation as a comprehensive consideration of user experience, device compatibility, and technical trends. The provided mechanisms give developers flexibility and enable rapid multi‑theme implementation, ultimately delivering higher‑quality products to users.

iOSfrontend developmentdark modetheme adaptationcross-platform UIROMA framework
JD Tech Talk
Written by

JD Tech Talk

Official JD Tech public account delivering best practices and technology innovation.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.