@@ -112,6 +112,9 @@ const badgeRef = useRef<UIKitViewRef<UIView>>(null);
112112await badgeRef .current ?.runOnUI ((view ) => {
113113 view .alpha = 0.8 ;
114114});
115+
116+ const measured = await badgeRef .current ?.measureNative ();
117+ badgeRef .current ?.invalidateNativeLayout ();
115118```
116119
117120React Native view props such as ` style ` , ` testID ` , accessibility props, responder
@@ -122,6 +125,118 @@ debug name, so native view descriptions can show `NativeScriptUIView` with your
122125definition name. It does not dynamically change the registered RN host component
123126tag.
124127
128+ ### Lifecycle and context
129+
130+ ` create ` , ` update ` , ` mounted ` , and ` dispose ` run through the UIKit path. You do
131+ not need to wrap UIKit work in ` runOnUI() ` inside those callbacks.
132+
133+ The first argument to ` create ` is also the current props object, so existing
134+ ` create(props) ` definitions keep working. New code can use the context helpers:
135+
136+ ``` tsx
137+ export const NativeSwitch = NativeScript .defineUIKitView <
138+ {value : boolean ; onValueChange ?: (value : boolean ) => void },
139+ UISwitch
140+ > ({
141+ name: " NativeSwitch" ,
142+ layout: {sizing: " intrinsic" },
143+ create(ctx ) {
144+ const view = UISwitch .new ();
145+ ctx .targetAction (view , UIControlEvents .ValueChanged , () => {
146+ ctx .emit (" onValueChange" , view .on );
147+ });
148+ return view ;
149+ },
150+ update(view , props ) {
151+ if (view .on !== props .value ) {
152+ view .setOnAnimated (props .value , false );
153+ }
154+ },
155+ });
156+ ```
157+
158+ Context helpers cover common native view-manager patterns:
159+
160+ - ` ctx.emit(name, payload) ` asynchronously calls the matching React prop.
161+ - ` ctx.targetAction(control, events, callback) ` retains and removes a target/action helper.
162+ - ` ctx.delegate(object, protocol, implementation) ` creates, assigns, and retains a delegate.
163+ - ` ctx.notification(name, object, callback) ` observes and removes notifications.
164+ - ` ctx.observe(object, keyPath, callback) ` observes and removes KVO.
165+ - ` ctx.retain(value) ` keeps native helper objects alive for the component lifetime.
166+ - ` ctx.dispose(callback) ` runs cleanup once, in reverse registration order.
167+ - ` ctx.invalidateLayout() ` schedules a fresh native measurement.
168+
169+ ### Layout
170+
171+ React Native owns placement through Yoga. UIKit owns native behavior inside the
172+ placed rectangle. Use ` layout.sizing ` to opt into native measurement:
173+
174+ - ` fill ` : fill the RN host bounds.
175+ - ` intrinsic ` : use ` intrinsicContentSize ` .
176+ - ` sizeThatFits ` : use ` sizeThatFits ` with style constraints.
177+ - ` autoLayout ` : use ` systemLayoutSizeFittingSize ` .
178+
179+ Use ` defaultSize ` , ` minSize ` , and ` maxSize ` when a native view can report zero
180+ or needs bounds during the first layout pass.
181+
182+ ``` tsx
183+ const NativeTitle = NativeScript .defineUIKitView <{text: string }, UILabel >({
184+ name: " NativeTitle" ,
185+ layout: {
186+ sizing: " intrinsic" ,
187+ defaultSize: {width: 1 , height: 1 },
188+ },
189+ create() {
190+ return UILabel .new ();
191+ },
192+ update(label , props , _previous , ctx ) {
193+ label .text = props .text ;
194+ ctx ?.invalidateLayout ();
195+ },
196+ });
197+ ```
198+
199+ ### Containers and view controllers
200+
201+ Use ` defineUIKitContainer() ` when React Native children should mount inside a
202+ UIKit-owned content view:
203+
204+ ``` tsx
205+ export const BlurCard = NativeScript .defineUIKitContainer ({
206+ name: " BlurCard" ,
207+ create() {
208+ const rootView = UIVisualEffectView .alloc ().initWithEffect (
209+ UIBlurEffect .effectWithStyle (UIBlurEffectStyle .SystemMaterial ),
210+ );
211+ return {
212+ rootView ,
213+ childrenView: rootView .contentView ,
214+ };
215+ },
216+ });
217+
218+ <BlurCard style = { {padding: 16 }} >
219+ <Text >React Native child content</Text >
220+ </BlurCard >;
221+ ```
222+
223+ Use ` defineUIViewController() ` for APIs that require real child view-controller
224+ containment:
225+
226+ ``` tsx
227+ export const NativePageHost = NativeScript .defineUIViewController ({
228+ name: " NativePageHost" ,
229+ createController() {
230+ return UIViewController .new ();
231+ },
232+ update(controller ) {
233+ controller .view .backgroundColor = UIColor .systemBackgroundColor ;
234+ },
235+ });
236+ ```
237+
238+ The package ships example definitions under ` @nativescript/react-native/examples ` .
239+
125240The published package includes generated NativeScript metadata, the libffi
126241xcframework, and generated iOS SDK TypeScript declarations. Build it from the
127242repository root with:
@@ -239,3 +354,41 @@ Expo development build, EAS Build, or `npx expo run:ios`.
239354
240355Set ` { "babelPlugin": false } ` in the config plugin options if you prefer to add
241356the Babel plugin manually.
357+
358+ The plugin also writes ` nativescript.react-native.json ` so metadata options are
359+ visible to native builds. You can pass metadata inputs when the app uses
360+ Objective-C-visible pods or extra system frameworks:
361+
362+ ``` json
363+ {
364+ "expo" : {
365+ "plugins" : [
366+ [
367+ " @nativescript/react-native" ,
368+ {
369+ "metadata" : {
370+ "includePods" : [" SomeObjCSDK" ],
371+ "includeSystemFrameworks" : [" UIKit" , " MapKit" , " WebKit" ]
372+ }
373+ }
374+ ]
375+ ]
376+ }
377+ }
378+ ```
379+
380+ ## Bare React Native setup helper
381+
382+ The tarball includes a small CLI for bare RN projects:
383+
384+ ``` sh
385+ npx nativescript-rn configure
386+ npx nativescript-rn generate-metadata --check
387+ cd ios
388+ RCT_NEW_ARCH_ENABLED=1 USE_HERMES=1 pod install
389+ ```
390+
391+ ` configure ` adds the bundled Babel plugin when missing, writes
392+ ` nativescript.react-native.json ` , and warns when the app is not configured for
393+ Hermes and the New Architecture. The command is intentionally conservative and
394+ does not make destructive native project edits.
0 commit comments