@@ -88,7 +88,7 @@ - (void)updateShadowStateInContextOfAncestorView:(nullable UIView *)ancestorView
8888
8989- (void )updateShadowStateInContextOfAncestorView : (nullable UIView *)ancestorView
9090{
91- [self updateShadowStateInContextOfAncestorView: ancestorView withFrame: self .frame ];
91+ [self updateShadowStateInContextOfAncestorView: ancestorView withFrame: self .bounds ];
9292}
9393
9494- (void )updateShadowStateWithFrame : (CGRect)frame
@@ -163,6 +163,10 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
163163- (void )updateLayoutMetrics : (const react::LayoutMetrics &)layoutMetrics
164164 oldLayoutMetrics : (const react::LayoutMetrics &)oldLayoutMetrics
165165{
166+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
167+ _layoutMetrics = layoutMetrics;
168+ [self invalidateIntrinsicContentSize ];
169+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
166170 CGRect frame = RCTCGRectFromRect (layoutMetrics.frame );
167171 // CALayer will crash if we pass NaN or Inf values.
168172 // It's unclear how to detect this case on cross-platform manner holistically, so we have to do it on the mounting
@@ -210,12 +214,52 @@ - (void)reactSetFrame:(CGRect)frame
210214- (UIBarButtonItem *)getUIBarButtonItem
211215{
212216 if (_barButtonItem == nil ) {
217+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
218+ // Starting from iOS 26, UIBarButtonItem's customView is streched to have at least 36 width.
219+ // Stretching RNSScreenStackHeaderSubview means that its subviews are aligned to left instead
220+ // of the center. To mitigate this, we add a wrapper view that will center
221+ // RNSScreenStackHeaderSubview inside of itself.
222+ UIView *wrapperView = [UIView new ];
223+ wrapperView.translatesAutoresizingMaskIntoConstraints = NO ;
224+
225+ self.translatesAutoresizingMaskIntoConstraints = NO ;
226+ [wrapperView addSubview: self ];
227+
228+ [self .centerXAnchor constraintEqualToAnchor: wrapperView.centerXAnchor].active = YES ;
229+ [self .centerYAnchor constraintEqualToAnchor: wrapperView.centerYAnchor].active = YES ;
230+
231+ // To prevent UIKit from stretching subviews to all available width, we need to:
232+ // 1. Set width of wrapperView to match RNSScreenStackHeaderSubview BUT when
233+ // RNSScreenStackHeaderSubview's width is smaller that minimal required 36 width, it breaks
234+ // UIKit's constraint. That's why we need to lower the priority of the constraint.
235+ NSLayoutConstraint *widthEqual = [wrapperView.widthAnchor constraintEqualToAnchor: self .widthAnchor];
236+ widthEqual.priority = UILayoutPriorityDefaultHigh;
237+ widthEqual.active = YES ;
238+
239+ NSLayoutConstraint *heightEqual = [wrapperView.heightAnchor constraintEqualToAnchor: self .heightAnchor];
240+ heightEqual.priority = UILayoutPriorityDefaultHigh;
241+ heightEqual.active = YES ;
242+
243+ // 2. Set content hugging prriority for RNSScreenStackHeaderSubview.
244+ [self setContentHuggingPriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisHorizontal];
245+ [self setContentHuggingPriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisVertical];
246+
247+ _barButtonItem = [[UIBarButtonItem alloc ] initWithCustomView: wrapperView];
248+ #else // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
213249 _barButtonItem = [[UIBarButtonItem alloc ] initWithCustomView: self ];
214- [ self configureBarButtonItem ];
250+ # endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
215251 }
252+
216253 return _barButtonItem;
217254}
218255
256+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
257+ - (CGSize)intrinsicContentSize
258+ {
259+ return RCTCGSizeFromSize (_layoutMetrics.frame .size );
260+ }
261+ #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
262+
219263- (void )configureBarButtonItem
220264{
221265#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
0 commit comments