react-native-navigation 8.8.4 → 8.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/RNNBasePresenter.mm +7 -0
- package/ios/RNNReactButtonView.h +2 -0
- package/ios/RNNReactButtonView.mm +143 -19
- package/ios/RNNStackController.mm +7 -0
- package/ios/RNNStackPresenter.h +4 -0
- package/ios/RNNStackPresenter.mm +8 -0
- package/ios/RNNUIBarButtonItem.h +1 -7
- package/ios/RNNUIBarButtonItem.mm +65 -30
- package/ios/TopBarAppearancePresenter.mm +115 -27
- package/ios/TopBarPresenter.h +6 -0
- package/ios/TopBarPresenter.mm +4 -0
- package/package.json +1 -1
package/ios/RNNBasePresenter.mm
CHANGED
|
@@ -144,6 +144,13 @@
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
- (UINavigationItem *)currentNavigationItem {
|
|
147
|
+
if ([self.boundViewController isKindOfClass:[UINavigationController class]]) {
|
|
148
|
+
UINavigationController *navigationController =
|
|
149
|
+
(UINavigationController *)self.boundViewController;
|
|
150
|
+
if (navigationController.topViewController) {
|
|
151
|
+
return navigationController.topViewController.navigationItem;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
147
154
|
return self.boundViewController.getCurrentChild.navigationItem;
|
|
148
155
|
}
|
|
149
156
|
|
package/ios/RNNReactButtonView.h
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#import "RNNReactButtonView.h"
|
|
2
2
|
#import <React/RCTSurface.h>
|
|
3
3
|
|
|
4
|
+
static const CGFloat kMinBarButtonSlotSize = 44.0;
|
|
5
|
+
|
|
4
6
|
@implementation RNNReactButtonView {
|
|
5
7
|
NSLayoutConstraint *_widthConstraint;
|
|
6
8
|
NSLayoutConstraint *_heightConstraint;
|
|
7
|
-
BOOL
|
|
9
|
+
BOOL _didCenterHorizontally;
|
|
10
|
+
CGFloat _lastReportedWidth;
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
- (instancetype)initWithHost:(RCTHost *)host
|
|
@@ -19,14 +22,16 @@
|
|
|
19
22
|
|
|
20
23
|
if (@available(iOS 26.0, *)) {
|
|
21
24
|
if (![self designRequiresCompatibility]) {
|
|
25
|
+
self.sizeFlexibility = RCTRootViewSizeFlexibilityWidth;
|
|
22
26
|
self.translatesAutoresizingMaskIntoConstraints = NO;
|
|
23
27
|
_widthConstraint = [self.widthAnchor constraintEqualToConstant:0];
|
|
24
|
-
_heightConstraint = [self.heightAnchor constraintEqualToConstant:
|
|
28
|
+
_heightConstraint = [self.heightAnchor constraintEqualToConstant:kMinBarButtonSlotSize];
|
|
25
29
|
_widthConstraint.priority = UILayoutPriorityDefaultHigh;
|
|
26
30
|
_heightConstraint.priority = UILayoutPriorityDefaultHigh;
|
|
27
31
|
_widthConstraint.active = YES;
|
|
28
32
|
_heightConstraint.active = YES;
|
|
29
|
-
|
|
33
|
+
_didCenterHorizontally = NO;
|
|
34
|
+
self.delegate = self;
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -43,37 +48,156 @@
|
|
|
43
48
|
return result;
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
- (UIView *)surfaceHostView {
|
|
52
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
53
|
+
UIView *surfaceView = (UIView *)self.surface.view;
|
|
54
|
+
if (surfaceView != nil && surfaceView.superview == self) {
|
|
55
|
+
return surfaceView;
|
|
56
|
+
}
|
|
57
|
+
#endif
|
|
58
|
+
return self.subviews.firstObject;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
- (void)accumulateLeafBoundsInContainer:(UIView *)container unionRect:(CGRect *)unionRect {
|
|
62
|
+
for (UIView *subview in container.subviews) {
|
|
63
|
+
if (subview.hidden || subview.alpha < 0.01) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (subview.subviews.count == 0) {
|
|
67
|
+
CGRect rect = [subview convertRect:subview.bounds toView:self];
|
|
68
|
+
if (rect.size.width > 0 && rect.size.height > 0) {
|
|
69
|
+
*unionRect = CGRectIsNull(*unionRect) ? rect : CGRectUnion(*unionRect, rect);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
[self accumulateLeafBoundsInContainer:subview unionRect:unionRect];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
- (CGRect)visibleLeafContentBounds {
|
|
78
|
+
CGRect unionRect = CGRectNull;
|
|
79
|
+
UIView *surfaceView = [self surfaceHostView];
|
|
80
|
+
if (surfaceView) {
|
|
81
|
+
[self accumulateLeafBoundsInContainer:surfaceView unionRect:&unionRect];
|
|
82
|
+
}
|
|
83
|
+
if (CGRectIsNull(unionRect)) {
|
|
84
|
+
[self accumulateLeafBoundsInContainer:self unionRect:&unionRect];
|
|
85
|
+
}
|
|
86
|
+
return CGRectIsNull(unionRect) ? CGRectZero : unionRect;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
- (CGSize)measuredSurfaceContentSize {
|
|
90
|
+
CGSize intrinsic = CGSizeZero;
|
|
91
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
92
|
+
intrinsic = self.surface.intrinsicSize;
|
|
93
|
+
#else
|
|
94
|
+
intrinsic = self.intrinsicContentSize;
|
|
95
|
+
#endif
|
|
96
|
+
if (intrinsic.width <= 0 || intrinsic.height <= 0) {
|
|
97
|
+
return CGSizeZero;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
CGFloat maxWidth = self.bounds.size.width > 0 ? self.bounds.size.width : CGFLOAT_MAX;
|
|
101
|
+
CGSize fit = [self sizeThatFits:CGSizeMake(maxWidth, CGFLOAT_MAX)];
|
|
102
|
+
if (fit.height > 0 && fit.height < intrinsic.height - 0.5) {
|
|
103
|
+
intrinsic.height = fit.height;
|
|
104
|
+
}
|
|
105
|
+
return intrinsic;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
- (void)centerSurfaceContentIfNeeded {
|
|
109
|
+
if (self.bounds.size.width <= 0 || self.bounds.size.height <= 0) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
UIView *surfaceView = [self surfaceHostView];
|
|
114
|
+
if (!surfaceView || surfaceView == self) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
CGRect surfaceFrame = surfaceView.frame;
|
|
119
|
+
if (surfaceFrame.size.width <= 0) {
|
|
120
|
+
surfaceFrame.size.width = self.bounds.size.width;
|
|
121
|
+
}
|
|
122
|
+
if (surfaceFrame.size.height <= 0) {
|
|
123
|
+
surfaceFrame.size.height = self.bounds.size.height;
|
|
124
|
+
}
|
|
125
|
+
surfaceView.frame = CGRectMake(0, 0, surfaceFrame.size.width, surfaceFrame.size.height);
|
|
126
|
+
|
|
127
|
+
CGRect contentBounds = [self visibleLeafContentBounds];
|
|
128
|
+
if (!CGRectIsEmpty(contentBounds)) {
|
|
129
|
+
CGFloat targetY = (self.bounds.size.height - contentBounds.size.height) / 2.0;
|
|
130
|
+
CGFloat deltaY = targetY - contentBounds.origin.y;
|
|
131
|
+
if (fabs(deltaY) > 0.5) {
|
|
132
|
+
surfaceView.frame = CGRectOffset(surfaceView.frame, 0, deltaY);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
CGSize contentSize = [self measuredSurfaceContentSize];
|
|
138
|
+
if (contentSize.height > 0 && self.bounds.size.height > contentSize.height + 0.5) {
|
|
139
|
+
CGFloat ty = (self.bounds.size.height - contentSize.height) / 2.0;
|
|
140
|
+
surfaceView.frame = CGRectMake(0, ty, self.bounds.size.width, contentSize.height);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
- (void)handleIntrinsicSizeChange:(CGSize)intrinsicSize {
|
|
145
|
+
if (intrinsicSize.width <= 0 || intrinsicSize.height <= 0) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
CGFloat width = MAX(intrinsicSize.width, kMinBarButtonSlotSize);
|
|
150
|
+
if (_widthConstraint && _heightConstraint) {
|
|
151
|
+
_widthConstraint.constant = width;
|
|
152
|
+
_heightConstraint.constant = kMinBarButtonSlotSize;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (self.intrinsicSizeDidChangeHandler && width > kMinBarButtonSlotSize &&
|
|
156
|
+
width > _lastReportedWidth) {
|
|
157
|
+
_lastReportedWidth = width;
|
|
158
|
+
self.intrinsicSizeDidChangeHandler(intrinsicSize);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
[self setNeedsLayout];
|
|
162
|
+
}
|
|
163
|
+
|
|
46
164
|
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag {
|
|
47
165
|
if (self.surface.rootTag == rootTag) {
|
|
48
166
|
[super didMountComponentsWithRootTag:rootTag];
|
|
49
167
|
[self sizeToFit];
|
|
50
|
-
|
|
51
|
-
if (![self designRequiresCompatibility]) {
|
|
52
|
-
[self updateConstraintsToFitSize];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
168
|
+
[self setNeedsLayout];
|
|
55
169
|
}
|
|
56
170
|
}
|
|
57
171
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
172
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
173
|
+
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize {
|
|
174
|
+
[self handleIntrinsicSizeChange:intrinsicSize];
|
|
175
|
+
}
|
|
176
|
+
#else
|
|
177
|
+
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {
|
|
178
|
+
[self handleIntrinsicSizeChange:rootView.intrinsicContentSize];
|
|
179
|
+
[rootView setNeedsUpdateConstraints];
|
|
180
|
+
[rootView updateConstraintsIfNeeded];
|
|
64
181
|
}
|
|
182
|
+
#endif
|
|
65
183
|
|
|
66
184
|
- (void)layoutSubviews {
|
|
67
185
|
[super layoutSubviews];
|
|
68
186
|
if (@available(iOS 26.0, *)) {
|
|
69
|
-
if ([self designRequiresCompatibility])
|
|
70
|
-
|
|
187
|
+
if ([self designRequiresCompatibility]) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
[self centerSurfaceContentIfNeeded];
|
|
192
|
+
|
|
193
|
+
if (!_didCenterHorizontally && self.superview && self.frame.size.width > 0) {
|
|
71
194
|
CGFloat wrapperWidth = self.superview.bounds.size.width;
|
|
72
195
|
CGFloat selfWidth = self.frame.size.width;
|
|
73
|
-
if (wrapperWidth > selfWidth) {
|
|
74
|
-
|
|
196
|
+
if (wrapperWidth > selfWidth + 0.5) {
|
|
197
|
+
_didCenterHorizontally = YES;
|
|
75
198
|
CGFloat tx = (wrapperWidth - selfWidth) / 2.0;
|
|
76
|
-
self.layer.affineTransform
|
|
199
|
+
CGAffineTransform transform = self.layer.affineTransform;
|
|
200
|
+
self.layer.affineTransform = CGAffineTransformMakeTranslation(tx, transform.ty);
|
|
77
201
|
}
|
|
78
202
|
}
|
|
79
203
|
}
|
|
@@ -28,6 +28,13 @@
|
|
|
28
28
|
return self;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
|
|
32
|
+
if (@available(iOS 26.0, *)) {
|
|
33
|
+
[self.presenter applyTopBarBackgroundBeforeShowingViewController:viewController];
|
|
34
|
+
}
|
|
35
|
+
[super pushViewController:viewController animated:animated];
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
- (void)viewDidLayoutSubviews {
|
|
32
39
|
[super viewDidLayoutSubviews];
|
|
33
40
|
[self.presenter applyOptionsOnViewDidLayoutSubviews:self.resolveOptions];
|
package/ios/RNNStackPresenter.h
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import "RNNBasePresenter.h"
|
|
2
2
|
#import "RNNComponentViewCreator.h"
|
|
3
3
|
#import "RNNReactComponentRegistry.h"
|
|
4
|
+
#import <UIKit/UIKit.h>
|
|
4
5
|
|
|
5
6
|
@interface RNNStackPresenter : RNNBasePresenter
|
|
6
7
|
|
|
@@ -9,6 +10,9 @@
|
|
|
9
10
|
|
|
10
11
|
- (void)applyOptionsBeforePopping:(RNNNavigationOptions *)options;
|
|
11
12
|
|
|
13
|
+
- (void)applyTopBarBackgroundBeforeShowingViewController:(UIViewController *)viewController
|
|
14
|
+
API_AVAILABLE(ios(26.0));
|
|
15
|
+
|
|
12
16
|
- (BOOL)shouldPopItem:(UINavigationItem *)item options:(RNNNavigationOptions *)options;
|
|
13
17
|
|
|
14
18
|
@end
|
package/ios/RNNStackPresenter.mm
CHANGED
|
@@ -101,6 +101,14 @@
|
|
|
101
101
|
[_topBarPresenter applyOptionsBeforePopping:options.topBar];
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
- (void)applyTopBarBackgroundBeforeShowingViewController:(UIViewController *)viewController {
|
|
105
|
+
if (@available(iOS 26.0, *)) {
|
|
106
|
+
RNNNavigationOptions *withDefault = viewController.resolveOptionsWithDefault;
|
|
107
|
+
[_topBarPresenter applyBackgroundForTransitionToViewController:viewController
|
|
108
|
+
topBarOptions:withDefault.topBar];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
104
112
|
- (void)mergeOptions:(RNNNavigationOptions *)mergeOptions
|
|
105
113
|
resolvedOptions:(RNNNavigationOptions *)resolvedOptions {
|
|
106
114
|
[super mergeOptions:mergeOptions resolvedOptions:resolvedOptions];
|
package/ios/RNNUIBarButtonItem.h
CHANGED
|
@@ -7,13 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
typedef void (^RNNButtonPressCallback)(NSString *buttonId);
|
|
9
9
|
|
|
10
|
-
@interface RNNUIBarButtonItem : UIBarButtonItem
|
|
11
|
-
#ifdef RCT_NEW_ARCH_ENABLED
|
|
12
|
-
RCTSurfaceDelegate
|
|
13
|
-
#else
|
|
14
|
-
RCTRootViewDelegate
|
|
15
|
-
#endif
|
|
16
|
-
>
|
|
10
|
+
@interface RNNUIBarButtonItem : UIBarButtonItem
|
|
17
11
|
|
|
18
12
|
@property(nonatomic, strong) NSString *buttonId;
|
|
19
13
|
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
#import <React/RCTSurface.h>
|
|
8
8
|
#endif
|
|
9
9
|
|
|
10
|
+
static const CGFloat kMinBarButtonSlotSize = 44.0;
|
|
11
|
+
|
|
10
12
|
@interface RNNUIBarButtonItem ()
|
|
11
13
|
|
|
12
14
|
@property(nonatomic, strong) NSLayoutConstraint *widthConstraint;
|
|
@@ -18,6 +20,7 @@
|
|
|
18
20
|
@implementation RNNUIBarButtonItem {
|
|
19
21
|
RNNIconCreator *_iconCreator;
|
|
20
22
|
RNNButtonOptions *_buttonOptions;
|
|
23
|
+
BOOL _didApplyWidthResize;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
- (instancetype)init {
|
|
@@ -94,6 +97,49 @@
|
|
|
94
97
|
return self;
|
|
95
98
|
}
|
|
96
99
|
|
|
100
|
+
- (BOOL)designRequiresCompatibility {
|
|
101
|
+
static BOOL checked = NO;
|
|
102
|
+
static BOOL result = NO;
|
|
103
|
+
if (!checked) {
|
|
104
|
+
checked = YES;
|
|
105
|
+
result = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIDesignRequiresCompatibility"] boolValue];
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (void)applyCustomViewIntrinsicSize:(CGSize)intrinsicSize {
|
|
111
|
+
if (!self.widthConstraint || !self.heightConstraint || intrinsicSize.width <= 0) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
CGFloat width = MAX(intrinsicSize.width, kMinBarButtonSlotSize);
|
|
116
|
+
if (_didApplyWidthResize && width <= self.widthConstraint.constant) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (self.widthConstraint.constant == width) {
|
|
121
|
+
_didApplyWidthResize = YES;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
self.widthConstraint.constant = width;
|
|
126
|
+
_didApplyWidthResize = YES;
|
|
127
|
+
|
|
128
|
+
[self.customView setNeedsLayout];
|
|
129
|
+
[self invalidateNavigationBarLayout];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
- (void)invalidateNavigationBarLayout {
|
|
133
|
+
UIView *view = self.customView;
|
|
134
|
+
while (view) {
|
|
135
|
+
if ([view isKindOfClass:[UINavigationBar class]]) {
|
|
136
|
+
[view setNeedsLayout];
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
view = view.superview;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
97
143
|
- (instancetype)initWithCustomView:(RNNReactView *)reactView
|
|
98
144
|
buttonOptions:(RNNButtonOptions *)buttonOptions
|
|
99
145
|
onPress:(RNNButtonPressCallback)onPress {
|
|
@@ -106,16 +152,25 @@
|
|
|
106
152
|
// back in via the hideSharedBackground option.
|
|
107
153
|
self.hidesSharedBackground =
|
|
108
154
|
[buttonOptions.hideSharedBackground withDefault:YES];
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
155
|
+
if (![self designRequiresCompatibility]) {
|
|
156
|
+
// Reserve a stable 44pt slot for push-transition snapshots, then grow
|
|
157
|
+
// width once when React reports intrinsic size (e.g. wide pickers).
|
|
158
|
+
// Height stays 44; vertical alignment is handled in React.
|
|
159
|
+
reactView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
160
|
+
self.widthConstraint = [reactView.widthAnchor constraintEqualToConstant:kMinBarButtonSlotSize];
|
|
161
|
+
self.heightConstraint = [reactView.heightAnchor constraintEqualToConstant:kMinBarButtonSlotSize];
|
|
162
|
+
self.widthConstraint.priority = UILayoutPriorityRequired;
|
|
163
|
+
self.heightConstraint.priority = UILayoutPriorityRequired;
|
|
164
|
+
self.widthConstraint.active = YES;
|
|
165
|
+
self.heightConstraint.active = YES;
|
|
166
|
+
if ([reactView isKindOfClass:[RNNReactButtonView class]]) {
|
|
167
|
+
RNNReactButtonView *buttonView = (RNNReactButtonView *)reactView;
|
|
168
|
+
__weak RNNUIBarButtonItem *weakSelf = self;
|
|
169
|
+
buttonView.intrinsicSizeDidChangeHandler = ^(CGSize intrinsicSize) {
|
|
170
|
+
[weakSelf applyCustomViewIntrinsicSize:intrinsicSize];
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
119
174
|
}
|
|
120
175
|
[self applyOptions:buttonOptions];
|
|
121
176
|
self.onPress = onPress;
|
|
@@ -219,26 +274,6 @@
|
|
|
219
274
|
}
|
|
220
275
|
|
|
221
276
|
|
|
222
|
-
#ifdef RCT_NEW_ARCH_ENABLED
|
|
223
|
-
// TODO: Verify
|
|
224
|
-
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize {
|
|
225
|
-
self.widthConstraint.constant = intrinsicSize.width;
|
|
226
|
-
self.heightConstraint.constant = intrinsicSize.height;
|
|
227
|
-
[surface setSize:intrinsicSize];
|
|
228
|
-
//[rootView setNeedsUpdateConstraints];
|
|
229
|
-
//[rootView updateConstraintsIfNeeded];
|
|
230
|
-
//surface.hidden = NO;
|
|
231
|
-
}
|
|
232
|
-
#else
|
|
233
|
-
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {
|
|
234
|
-
self.widthConstraint.constant = rootView.intrinsicContentSize.width;
|
|
235
|
-
self.heightConstraint.constant = rootView.intrinsicContentSize.height;
|
|
236
|
-
[rootView setNeedsUpdateConstraints];
|
|
237
|
-
[rootView updateConstraintsIfNeeded];
|
|
238
|
-
rootView.hidden = NO;
|
|
239
|
-
}
|
|
240
|
-
#endif
|
|
241
|
-
|
|
242
277
|
- (void)onButtonPressed:(RNNUIBarButtonItem *)barButtonItem {
|
|
243
278
|
self.onPress(self.buttonId);
|
|
244
279
|
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
#import "TopBarAppearancePresenter.h"
|
|
2
2
|
#import "RNNFontAttributesCreator.h"
|
|
3
|
+
#import "UIColor+RNNUtils.h"
|
|
4
|
+
#import "UIImage+utils.h"
|
|
3
5
|
#import "UIViewController+LayoutProtocol.h"
|
|
4
6
|
|
|
5
7
|
@interface TopBarAppearancePresenter ()
|
|
6
8
|
|
|
9
|
+
- (void)applyBackgroundToNavigationItem:(UINavigationItem *)item topBarOptions:(RNNTopBarOptions *)options;
|
|
10
|
+
- (void)syncNavigationBarAppearanceFromNavigationItem:(UINavigationItem *)item;
|
|
11
|
+
- (void)applyBackgroundToAppearance:(UINavigationBarAppearance *)appearance
|
|
12
|
+
withOpaqueColor:(UIColor *)color
|
|
13
|
+
transparent:(BOOL)transparent
|
|
14
|
+
translucent:(BOOL)translucent;
|
|
15
|
+
|
|
7
16
|
@end
|
|
8
17
|
|
|
9
18
|
@implementation TopBarAppearancePresenter
|
|
@@ -11,6 +20,97 @@
|
|
|
11
20
|
@synthesize borderColor = _borderColor;
|
|
12
21
|
@synthesize scrollEdgeBorderColor = _scrollEdgeBorderColor;
|
|
13
22
|
|
|
23
|
+
- (void)applyBackgroundToNavigationItem:(UINavigationItem *)item topBarOptions:(RNNTopBarOptions *)options {
|
|
24
|
+
UIColor *color = [options.background.color withDefault:nil];
|
|
25
|
+
BOOL transparent = color.isTransparent;
|
|
26
|
+
BOOL translucent = [options.background.translucent withDefault:NO];
|
|
27
|
+
|
|
28
|
+
if (!item.standardAppearance) {
|
|
29
|
+
item.standardAppearance = [UINavigationBarAppearance new];
|
|
30
|
+
}
|
|
31
|
+
if (!item.scrollEdgeAppearance) {
|
|
32
|
+
item.scrollEdgeAppearance = [UINavigationBarAppearance new];
|
|
33
|
+
}
|
|
34
|
+
[self applyBackgroundToAppearance:item.standardAppearance
|
|
35
|
+
withOpaqueColor:color
|
|
36
|
+
transparent:transparent
|
|
37
|
+
translucent:translucent];
|
|
38
|
+
[self applyBackgroundToAppearance:item.scrollEdgeAppearance
|
|
39
|
+
withOpaqueColor:color
|
|
40
|
+
transparent:transparent
|
|
41
|
+
translucent:translucent];
|
|
42
|
+
|
|
43
|
+
if ([options.scrollEdgeAppearance.active withDefault:NO]) {
|
|
44
|
+
UIColor *scrollEdgeColor = [options.scrollEdgeAppearance.background.color withDefault:nil];
|
|
45
|
+
BOOL scrollEdgeTransparent = scrollEdgeColor.isTransparent;
|
|
46
|
+
BOOL scrollEdgeTranslucent =
|
|
47
|
+
[options.scrollEdgeAppearance.background.translucent withDefault:translucent];
|
|
48
|
+
UIColor *resolvedScrollEdgeColor = scrollEdgeColor ?: color;
|
|
49
|
+
[self applyBackgroundToAppearance:item.scrollEdgeAppearance
|
|
50
|
+
withOpaqueColor:resolvedScrollEdgeColor
|
|
51
|
+
transparent:scrollEdgeTransparent
|
|
52
|
+
translucent:scrollEdgeTranslucent];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (@available(iOS 26.0, *)) {
|
|
56
|
+
[self syncNavigationBarAppearanceFromNavigationItem:item];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
- (void)applyBackgroundForTransitionToViewController:(UIViewController *)viewController
|
|
61
|
+
topBarOptions:(RNNTopBarOptions *)options {
|
|
62
|
+
if (@available(iOS 26.0, *)) {
|
|
63
|
+
[self applyBackgroundToNavigationItem:viewController.navigationItem topBarOptions:options];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (void)syncNavigationBarAppearanceFromNavigationItem:(UINavigationItem *)item {
|
|
68
|
+
UINavigationBar *navigationBar = self.navigationController.navigationBar;
|
|
69
|
+
if (item.standardAppearance) {
|
|
70
|
+
navigationBar.standardAppearance = [item.standardAppearance copy];
|
|
71
|
+
}
|
|
72
|
+
UINavigationBarAppearance *scrollEdgeAppearance =
|
|
73
|
+
item.scrollEdgeAppearance ?: item.standardAppearance;
|
|
74
|
+
if (scrollEdgeAppearance) {
|
|
75
|
+
navigationBar.scrollEdgeAppearance = [scrollEdgeAppearance copy];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- (void)applyBackgroundToAppearance:(UINavigationBarAppearance *)appearance
|
|
80
|
+
withOpaqueColor:(UIColor *)color
|
|
81
|
+
transparent:(BOOL)transparent
|
|
82
|
+
translucent:(BOOL)translucent {
|
|
83
|
+
if (transparent || color.isTransparent) {
|
|
84
|
+
[appearance configureWithTransparentBackground];
|
|
85
|
+
if (@available(iOS 26.0, *)) {
|
|
86
|
+
appearance.backgroundEffect = nil;
|
|
87
|
+
appearance.backgroundColor = UIColor.clearColor;
|
|
88
|
+
appearance.backgroundImage = nil;
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (color) {
|
|
94
|
+
if (@available(iOS 26.0, *)) {
|
|
95
|
+
[appearance configureWithTransparentBackground];
|
|
96
|
+
appearance.backgroundEffect = nil;
|
|
97
|
+
appearance.shadowColor = nil;
|
|
98
|
+
appearance.backgroundColor = color;
|
|
99
|
+
appearance.backgroundImage = [UIImage imageWithSize:CGSizeMake(1, 1) color:color];
|
|
100
|
+
} else {
|
|
101
|
+
[appearance configureWithOpaqueBackground];
|
|
102
|
+
appearance.backgroundColor = color;
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (translucent) {
|
|
108
|
+
[appearance configureWithDefaultBackground];
|
|
109
|
+
} else {
|
|
110
|
+
[appearance configureWithOpaqueBackground];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
14
114
|
- (void)applyOptions:(RNNTopBarOptions *)options {
|
|
15
115
|
[self setTranslucent:[options.background.translucent withDefault:NO]];
|
|
16
116
|
[self
|
|
@@ -77,36 +177,24 @@
|
|
|
77
177
|
}
|
|
78
178
|
|
|
79
179
|
- (void)updateScrollEdgeAppearance {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} else if (self.scrollEdgeTranslucent) {
|
|
86
|
-
[self.getScrollEdgeAppearance configureWithDefaultBackground];
|
|
87
|
-
} else {
|
|
88
|
-
[self.getScrollEdgeAppearance configureWithOpaqueBackground];
|
|
89
|
-
if (self.backgroundColor) {
|
|
90
|
-
[self.getScrollEdgeAppearance setBackgroundColor:self.backgroundColor];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
180
|
+
UIColor *color = self.scrollEdgeAppearanceColor ?: self.backgroundColor;
|
|
181
|
+
[self applyBackgroundToAppearance:self.getScrollEdgeAppearance
|
|
182
|
+
withOpaqueColor:color
|
|
183
|
+
transparent:self.scrollEdgeTransparent
|
|
184
|
+
translucent:self.scrollEdgeTranslucent];
|
|
93
185
|
}
|
|
94
186
|
|
|
95
187
|
- (void)updateBackgroundAppearance {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[self.
|
|
106
|
-
[self.getScrollEdgeAppearance configureWithDefaultBackground];
|
|
107
|
-
} else {
|
|
108
|
-
[self.getAppearance configureWithOpaqueBackground];
|
|
109
|
-
[self.getScrollEdgeAppearance configureWithOpaqueBackground];
|
|
188
|
+
[self applyBackgroundToAppearance:self.getAppearance
|
|
189
|
+
withOpaqueColor:self.backgroundColor
|
|
190
|
+
transparent:self.transparent
|
|
191
|
+
translucent:self.translucent];
|
|
192
|
+
[self applyBackgroundToAppearance:self.getScrollEdgeAppearance
|
|
193
|
+
withOpaqueColor:self.backgroundColor
|
|
194
|
+
transparent:self.transparent
|
|
195
|
+
translucent:self.translucent];
|
|
196
|
+
if (@available(iOS 26.0, *)) {
|
|
197
|
+
[self syncNavigationBarAppearanceFromNavigationItem:self.currentNavigationItem];
|
|
110
198
|
}
|
|
111
199
|
}
|
|
112
200
|
|
package/ios/TopBarPresenter.h
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
#import "RNNBasePresenter.h"
|
|
2
2
|
#import "RNNTopBarOptions.h"
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
3
4
|
|
|
4
5
|
@interface TopBarPresenter : RNNBasePresenter
|
|
5
6
|
|
|
7
|
+
- (UINavigationController *)navigationController;
|
|
8
|
+
|
|
6
9
|
- (void)applyOptions:(RNNTopBarOptions *)options;
|
|
7
10
|
|
|
8
11
|
- (void)applyOptionsBeforePopping:(RNNTopBarOptions *)options;
|
|
9
12
|
|
|
13
|
+
- (void)applyBackgroundForTransitionToViewController:(UIViewController *)viewController
|
|
14
|
+
topBarOptions:(RNNTopBarOptions *)options API_AVAILABLE(ios(26.0));
|
|
15
|
+
|
|
10
16
|
- (void)mergeOptions:(RNNTopBarOptions *)options withDefault:(RNNTopBarOptions *)defaultOptions;
|
|
11
17
|
|
|
12
18
|
- (instancetype)initWithNavigationController:(UINavigationController *)boundNavigationController;
|
package/ios/TopBarPresenter.mm
CHANGED
|
@@ -71,6 +71,10 @@
|
|
|
71
71
|
[self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:image];
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
- (void)applyBackgroundForTransitionToViewController:(UIViewController *)viewController
|
|
75
|
+
topBarOptions:(RNNTopBarOptions *)options {
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
- (void)setBackgroundColor:(UIColor *)backgroundColor {
|
|
75
79
|
_backgroundColor = backgroundColor;
|
|
76
80
|
[self updateBackgroundAppearance];
|