react-native-platform-components 0.6.1 → 0.8.0

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.
Files changed (62) hide show
  1. package/README.md +259 -44
  2. package/android/src/main/java/com/platformcomponents/PCLiquidGlassView.kt +84 -0
  3. package/android/src/main/java/com/platformcomponents/PCLiquidGlassViewManager.kt +52 -0
  4. package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +241 -0
  5. package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +105 -0
  6. package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +2 -0
  7. package/ios/PCDatePickerView.swift +16 -13
  8. package/ios/PCLiquidGlass.h +10 -0
  9. package/ios/PCLiquidGlass.mm +140 -0
  10. package/ios/PCLiquidGlass.swift +354 -0
  11. package/ios/PCSegmentedControl.h +10 -0
  12. package/ios/PCSegmentedControl.mm +194 -0
  13. package/ios/PCSegmentedControl.swift +200 -0
  14. package/ios/PCSelectionMenu.swift +1 -1
  15. package/lib/commonjs/LiquidGlass.js +72 -0
  16. package/lib/commonjs/LiquidGlass.js.map +1 -0
  17. package/lib/commonjs/LiquidGlassNativeComponent.ts +110 -0
  18. package/lib/commonjs/SegmentedControl.js +93 -0
  19. package/lib/commonjs/SegmentedControl.js.map +1 -0
  20. package/lib/commonjs/SegmentedControlNativeComponent.ts +79 -0
  21. package/lib/commonjs/index.js +22 -0
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/module/LiquidGlass.js +64 -0
  24. package/lib/module/LiquidGlass.js.map +1 -0
  25. package/lib/module/LiquidGlassNativeComponent.ts +110 -0
  26. package/lib/module/SegmentedControl.js +87 -0
  27. package/lib/module/SegmentedControl.js.map +1 -0
  28. package/lib/module/SegmentedControlNativeComponent.ts +79 -0
  29. package/lib/module/index.js +2 -0
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/typescript/commonjs/src/LiquidGlass.d.ts +96 -0
  32. package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -0
  33. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +93 -0
  34. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -0
  35. package/lib/typescript/commonjs/src/SegmentedControl.d.ts +62 -0
  36. package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -0
  37. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +63 -0
  38. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -0
  39. package/lib/typescript/commonjs/src/index.d.ts +2 -0
  40. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  41. package/lib/typescript/module/src/LiquidGlass.d.ts +96 -0
  42. package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -0
  43. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +93 -0
  44. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -0
  45. package/lib/typescript/module/src/SegmentedControl.d.ts +62 -0
  46. package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -0
  47. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +63 -0
  48. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -0
  49. package/lib/typescript/module/src/index.d.ts +2 -0
  50. package/lib/typescript/module/src/index.d.ts.map +1 -1
  51. package/package.json +13 -4
  52. package/react-native.config.js +1 -0
  53. package/shared/PCSegmentedControlComponentDescriptors-custom.h +22 -0
  54. package/shared/PCSegmentedControlShadowNode-custom.cpp +54 -0
  55. package/shared/PCSegmentedControlShadowNode-custom.h +56 -0
  56. package/shared/PCSegmentedControlState-custom.h +62 -0
  57. package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +1 -0
  58. package/src/LiquidGlass.tsx +169 -0
  59. package/src/LiquidGlassNativeComponent.ts +110 -0
  60. package/src/SegmentedControl.tsx +178 -0
  61. package/src/SegmentedControlNativeComponent.ts +79 -0
  62. package/src/index.tsx +2 -0
@@ -0,0 +1,354 @@
1
+ import UIKit
2
+
3
+ /// Glass effect style enum for bridging to ObjC++
4
+ @objc public enum PCLiquidGlassEffectStyle: Int {
5
+ case regular
6
+ case clear
7
+ case none
8
+
9
+ #if compiler(>=6.2)
10
+ @available(iOS 26.0, *)
11
+ var glassStyle: UIGlassEffect.Style? {
12
+ switch self {
13
+ case .regular:
14
+ return .regular
15
+ case .clear:
16
+ return .clear
17
+ case .none:
18
+ return nil
19
+ }
20
+ }
21
+ #endif
22
+ }
23
+
24
+ #if compiler(>=6.2)
25
+
26
+ /// The actual Liquid Glass view implementation for iOS 26+
27
+ /// Extends UIVisualEffectView to properly support UIGlassEffect
28
+ @available(iOS 26.0, *)
29
+ @objcMembers
30
+ public final class PCLiquidGlassView: UIVisualEffectView {
31
+
32
+ // MARK: - Static
33
+
34
+ @objc public static var isSupported: Bool {
35
+ return true
36
+ }
37
+
38
+ // MARK: - Props (set from ObjC++)
39
+
40
+ private var isFirstMount: Bool = true
41
+
42
+ /// Effect style: "clear", "regular", "none"
43
+ public var effectStyle: String = "regular" {
44
+ didSet { applyGlassEffect() }
45
+ }
46
+
47
+ /// Corner radius for the glass effect
48
+ public var glassCornerRadius: CGFloat = 0 {
49
+ didSet { applyCornerRadius() }
50
+ }
51
+
52
+ /// Enable touch interaction feedback
53
+ public var interactive: Bool = false
54
+
55
+ /// Tint color for the glass effect (hex string)
56
+ public var glassTintColor: String? {
57
+ didSet { applyGlassEffect() }
58
+ }
59
+
60
+ /// Color scheme: "light", "dark", "system"
61
+ public var colorScheme: String = "system" {
62
+ didSet { applyColorScheme() }
63
+ }
64
+
65
+ /// Shadow radius for glow effect
66
+ public var glassShadowRadius: CGFloat = 20 {
67
+ didSet { applyShadow() }
68
+ }
69
+
70
+ /// Manual highlight state control (no-op on iOS 26+, use `interactive` instead)
71
+ /// The native UIGlassEffect.isInteractive handles touch-based highlighting automatically
72
+ public var isHighlighted: Bool = false
73
+
74
+ /// Callback for press events with touch coordinates
75
+ public var onPressCallback: ((CGFloat, CGFloat) -> Void)?
76
+
77
+ // MARK: - Init
78
+
79
+ public override init(effect: UIVisualEffect?) {
80
+ super.init(effect: effect)
81
+ setup()
82
+ }
83
+
84
+ public required init?(coder: NSCoder) {
85
+ super.init(coder: coder)
86
+ setup()
87
+ }
88
+
89
+ private func setup() {
90
+ clipsToBounds = false
91
+ setupTapGesture()
92
+ }
93
+
94
+ private func setupTapGesture() {
95
+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
96
+ addGestureRecognizer(tap)
97
+ }
98
+
99
+ @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
100
+ let location = gesture.location(in: self)
101
+ onPressCallback?(location.x, location.y)
102
+ }
103
+
104
+ // MARK: - Layout
105
+
106
+ public override func layoutSubviews() {
107
+ super.layoutSubviews()
108
+
109
+ // Apply glass effect on first layout when we have bounds
110
+ if effect == nil && bounds.size != .zero {
111
+ applyGlassEffect()
112
+ }
113
+ }
114
+
115
+ // MARK: - Public Setup (called from ObjC++ after props are set)
116
+
117
+ /// Call this after setting props to apply/re-apply the glass effect
118
+ @objc public func setupView() {
119
+ applyGlassEffect()
120
+ }
121
+
122
+ // MARK: - Glass Effect
123
+
124
+ private func applyGlassEffect() {
125
+ guard bounds.size != .zero else { return }
126
+
127
+ // Parse effect style
128
+ let style: PCLiquidGlassEffectStyle
129
+ switch effectStyle {
130
+ case "clear":
131
+ style = .clear
132
+ case "none":
133
+ style = .none
134
+ default:
135
+ style = .regular
136
+ }
137
+
138
+ // Handle "none" style
139
+ guard let glassStyle = style.glassStyle else {
140
+ UIView.animate(withDuration: 0.2) {
141
+ self.effect = nil
142
+ }
143
+ return
144
+ }
145
+
146
+ // Create the glass effect
147
+ let glassEffect = UIGlassEffect(style: glassStyle)
148
+ glassEffect.isInteractive = interactive
149
+
150
+ // Apply tint color
151
+ if let tintHex = glassTintColor, !tintHex.isEmpty,
152
+ let color = UIColor(pcHex: tintHex) {
153
+ glassEffect.tintColor = color
154
+ }
155
+
156
+ // Apply the effect
157
+ if isFirstMount {
158
+ self.effect = glassEffect
159
+ isFirstMount = false
160
+ } else {
161
+ UIView.animate(withDuration: 0.2) {
162
+ self.effect = glassEffect
163
+ }
164
+ }
165
+
166
+ applyCornerRadius()
167
+ applyShadow()
168
+ }
169
+
170
+ private func applyCornerRadius() {
171
+ layer.cornerRadius = glassCornerRadius
172
+ layer.cornerCurve = .continuous
173
+ // Don't clip to bounds - allow shadow to show
174
+ }
175
+
176
+ private func applyShadow() {
177
+ if glassShadowRadius > 0 {
178
+ layer.shadowColor = UIColor.white.cgColor
179
+ layer.shadowOpacity = 0.2
180
+ layer.shadowRadius = glassShadowRadius
181
+ layer.shadowOffset = .zero
182
+ layer.masksToBounds = false
183
+ } else {
184
+ layer.shadowOpacity = 0
185
+ }
186
+ }
187
+
188
+ private func applyColorScheme() {
189
+ switch colorScheme {
190
+ case "light":
191
+ overrideUserInterfaceStyle = .light
192
+ case "dark":
193
+ overrideUserInterfaceStyle = .dark
194
+ default:
195
+ overrideUserInterfaceStyle = .unspecified
196
+ }
197
+ applyGlassEffect()
198
+ }
199
+
200
+ // MARK: - Sizing
201
+
202
+ public override func sizeThatFits(_ size: CGSize) -> CGSize {
203
+ return size
204
+ }
205
+
206
+ public override var intrinsicContentSize: CGSize {
207
+ return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
208
+ }
209
+ }
210
+
211
+ #else
212
+
213
+ /// Fallback for older Swift compilers (pre-iOS 26 SDK)
214
+ /// Uses UIBlurEffect as a fallback
215
+ @objcMembers
216
+ public final class PCLiquidGlassView: UIVisualEffectView {
217
+
218
+ @objc public static var isSupported: Bool {
219
+ return false
220
+ }
221
+
222
+ public var effectStyle: String = "regular" {
223
+ didSet { applyFallbackEffect() }
224
+ }
225
+
226
+ public var glassCornerRadius: CGFloat = 0 {
227
+ didSet { applyCornerRadius() }
228
+ }
229
+
230
+ public var interactive: Bool = false
231
+ public var glassTintColor: String?
232
+ public var colorScheme: String = "system" {
233
+ didSet { applyColorScheme() }
234
+ }
235
+ public var glassShadowRadius: CGFloat = 20
236
+ public var isHighlighted: Bool = false
237
+ public var onPressCallback: ((CGFloat, CGFloat) -> Void)?
238
+
239
+ public override init(effect: UIVisualEffect?) {
240
+ super.init(effect: effect)
241
+ setup()
242
+ }
243
+
244
+ public required init?(coder: NSCoder) {
245
+ super.init(coder: coder)
246
+ setup()
247
+ }
248
+
249
+ private func setup() {
250
+ clipsToBounds = false
251
+ setupTapGesture()
252
+ applyFallbackEffect()
253
+ }
254
+
255
+ private func setupTapGesture() {
256
+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
257
+ addGestureRecognizer(tap)
258
+ }
259
+
260
+ @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
261
+ let location = gesture.location(in: self)
262
+ onPressCallback?(location.x, location.y)
263
+ }
264
+
265
+ public override func layoutSubviews() {
266
+ super.layoutSubviews()
267
+ if effect == nil && bounds.size != .zero {
268
+ applyFallbackEffect()
269
+ }
270
+ }
271
+
272
+ /// Call this after setting props to apply/re-apply the effect
273
+ @objc public func setupView() {
274
+ applyFallbackEffect()
275
+ }
276
+
277
+ private func applyFallbackEffect() {
278
+ guard effectStyle != "none" else {
279
+ self.effect = nil
280
+ return
281
+ }
282
+
283
+ // Use thin blur materials as fallback
284
+ let blurStyle: UIBlurEffect.Style
285
+ switch (effectStyle, colorScheme) {
286
+ case ("clear", "dark"):
287
+ blurStyle = .systemUltraThinMaterialDark
288
+ case ("clear", "light"):
289
+ blurStyle = .systemUltraThinMaterialLight
290
+ case ("clear", _):
291
+ blurStyle = .systemUltraThinMaterial
292
+ case (_, "dark"):
293
+ blurStyle = .systemThinMaterialDark
294
+ case (_, "light"):
295
+ blurStyle = .systemThinMaterialLight
296
+ default:
297
+ blurStyle = .systemThinMaterial
298
+ }
299
+
300
+ self.effect = UIBlurEffect(style: blurStyle)
301
+ applyCornerRadius()
302
+ }
303
+
304
+ private func applyCornerRadius() {
305
+ layer.cornerRadius = glassCornerRadius
306
+ layer.cornerCurve = .continuous
307
+ clipsToBounds = glassCornerRadius > 0
308
+ }
309
+
310
+ private func applyColorScheme() {
311
+ switch colorScheme {
312
+ case "light":
313
+ overrideUserInterfaceStyle = .light
314
+ case "dark":
315
+ overrideUserInterfaceStyle = .dark
316
+ default:
317
+ overrideUserInterfaceStyle = .unspecified
318
+ }
319
+ applyFallbackEffect()
320
+ }
321
+ }
322
+
323
+ #endif
324
+
325
+ // MARK: - UIColor hex extension
326
+
327
+ private extension UIColor {
328
+ convenience init?(pcHex: String) {
329
+ var hexSanitized = pcHex.trimmingCharacters(in: .whitespacesAndNewlines)
330
+ hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")
331
+
332
+ var rgb: UInt64 = 0
333
+ guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }
334
+
335
+ let length = hexSanitized.count
336
+ if length == 6 {
337
+ self.init(
338
+ red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0,
339
+ green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0,
340
+ blue: CGFloat(rgb & 0x0000FF) / 255.0,
341
+ alpha: 1.0
342
+ )
343
+ } else if length == 8 {
344
+ self.init(
345
+ red: CGFloat((rgb & 0xFF000000) >> 24) / 255.0,
346
+ green: CGFloat((rgb & 0x00FF0000) >> 16) / 255.0,
347
+ blue: CGFloat((rgb & 0x0000FF00) >> 8) / 255.0,
348
+ alpha: CGFloat(rgb & 0x000000FF) / 255.0
349
+ )
350
+ } else {
351
+ return nil
352
+ }
353
+ }
354
+ }
@@ -0,0 +1,10 @@
1
+ // PCSegmentedControl.h
2
+
3
+ #import <React/RCTViewComponentView.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface PCSegmentedControl : RCTViewComponentView
8
+ @end
9
+
10
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,194 @@
1
+ // PCSegmentedControl.mm
2
+
3
+ #import "PCSegmentedControl.h"
4
+
5
+ #import <React/RCTComponentViewFactory.h>
6
+ #import <React/RCTConversions.h>
7
+ #import <React/RCTFabricComponentsPlugins.h>
8
+
9
+ #import <react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h>
10
+ #import <react/renderer/components/PlatformComponentsViewSpec/EventEmitters.h>
11
+ #import <react/renderer/components/PlatformComponentsViewSpec/Props.h>
12
+ #import <react/renderer/core/LayoutPrimitives.h>
13
+
14
+ #if __has_include(<PlatformComponents/PlatformComponents-Swift.h>)
15
+ #import <PlatformComponents/PlatformComponents-Swift.h>
16
+ #else
17
+ #import "PlatformComponents-Swift.h"
18
+ #endif
19
+
20
+ #import "PCSegmentedControlComponentDescriptors-custom.h"
21
+ #import "PCSegmentedControlShadowNode-custom.h"
22
+ #import "PCSegmentedControlState-custom.h"
23
+
24
+ using namespace facebook::react;
25
+
26
+ namespace {
27
+ static inline bool SegmentsEqual(
28
+ const std::vector<facebook::react::PCSegmentedControlSegmentsStruct> &a,
29
+ const std::vector<facebook::react::PCSegmentedControlSegmentsStruct> &b) {
30
+ if (a.size() != b.size()) return false;
31
+ for (size_t i = 0; i < a.size(); i++) {
32
+ if (a[i].label != b[i].label) return false;
33
+ if (a[i].value != b[i].value) return false;
34
+ if (a[i].disabled != b[i].disabled) return false;
35
+ if (a[i].icon != b[i].icon) return false;
36
+ }
37
+ return true;
38
+ }
39
+ } // namespace
40
+
41
+ @interface PCSegmentedControl ()
42
+
43
+ - (void)updateMeasurements;
44
+
45
+ @end
46
+
47
+ @implementation PCSegmentedControl {
48
+ PCSegmentedControlView *_view;
49
+ MeasuringPCSegmentedControlShadowNode::ConcreteState::Shared _state;
50
+ }
51
+
52
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
53
+ return concreteComponentDescriptorProvider<
54
+ MeasuringPCSegmentedControlComponentDescriptor>();
55
+ }
56
+
57
+ - (instancetype)initWithFrame:(CGRect)frame {
58
+ if (self = [super initWithFrame:frame]) {
59
+ _view = [PCSegmentedControlView new];
60
+ self.contentView = _view;
61
+
62
+ __weak __typeof(self) weakSelf = self;
63
+
64
+ _view.onSelect = ^(NSInteger index, NSString *value) {
65
+ __typeof(self) strongSelf = weakSelf;
66
+ if (!strongSelf) return;
67
+
68
+ auto eventEmitter =
69
+ std::static_pointer_cast<const PCSegmentedControlEventEmitter>(
70
+ strongSelf->_eventEmitter);
71
+ if (!eventEmitter) return;
72
+
73
+ PCSegmentedControlEventEmitter::OnSelect payload = {
74
+ .index = (int)index,
75
+ .value = value.UTF8String,
76
+ };
77
+
78
+ eventEmitter->onSelect(payload);
79
+ };
80
+ }
81
+ return self;
82
+ }
83
+
84
+ - (void)updateProps:(Props::Shared const &)props
85
+ oldProps:(Props::Shared const &)oldProps {
86
+ const auto &newProps =
87
+ *std::static_pointer_cast<const PCSegmentedControlProps>(props);
88
+ const auto prevProps =
89
+ std::static_pointer_cast<const PCSegmentedControlProps>(oldProps);
90
+
91
+ // segments: [{label, value, disabled, icon}]
92
+ if (!prevProps || !SegmentsEqual(newProps.segments, prevProps->segments)) {
93
+ NSMutableArray *arr = [NSMutableArray new];
94
+ for (const auto &seg : newProps.segments) {
95
+ NSString *label = seg.label.empty()
96
+ ? @""
97
+ : [NSString stringWithUTF8String:seg.label.c_str()];
98
+ NSString *value = seg.value.empty()
99
+ ? @""
100
+ : [NSString stringWithUTF8String:seg.value.c_str()];
101
+ NSString *disabled = seg.disabled.empty()
102
+ ? @"enabled"
103
+ : [NSString stringWithUTF8String:seg.disabled.c_str()];
104
+ NSString *icon = seg.icon.empty()
105
+ ? @""
106
+ : [NSString stringWithUTF8String:seg.icon.c_str()];
107
+ [arr addObject:@{
108
+ @"label": label,
109
+ @"value": value,
110
+ @"disabled": disabled,
111
+ @"icon": icon
112
+ }];
113
+ }
114
+ _view.segments = arr;
115
+ }
116
+
117
+ // selectedValue (default "")
118
+ if (!prevProps || newProps.selectedValue != prevProps->selectedValue) {
119
+ if (!newProps.selectedValue.empty()) {
120
+ _view.selectedValue =
121
+ [NSString stringWithUTF8String:newProps.selectedValue.c_str()];
122
+ } else {
123
+ _view.selectedValue = @""; // sentinel for no selection
124
+ }
125
+ }
126
+
127
+ // interactivity: "enabled" | "disabled"
128
+ if (!prevProps || newProps.interactivity != prevProps->interactivity) {
129
+ if (!newProps.interactivity.empty()) {
130
+ _view.interactivity =
131
+ [NSString stringWithUTF8String:newProps.interactivity.c_str()];
132
+ } else {
133
+ _view.interactivity = @"enabled";
134
+ }
135
+ }
136
+
137
+ // iOS-specific props
138
+ const auto &newIos = newProps.ios;
139
+ const auto &oldIos =
140
+ prevProps ? prevProps->ios : PCSegmentedControlIosStruct{};
141
+
142
+ if (!prevProps || newIos.momentary != oldIos.momentary) {
143
+ _view.momentary = (newIos.momentary == "true");
144
+ }
145
+
146
+ if (!prevProps || newIos.apportionsSegmentWidthsByContent != oldIos.apportionsSegmentWidthsByContent) {
147
+ _view.apportionsSegmentWidthsByContent = (newIos.apportionsSegmentWidthsByContent == "true");
148
+ }
149
+
150
+ if (!prevProps || newIos.selectedSegmentTintColor != oldIos.selectedSegmentTintColor) {
151
+ if (!newIos.selectedSegmentTintColor.empty()) {
152
+ _view.selectedSegmentTintColor =
153
+ [NSString stringWithUTF8String:newIos.selectedSegmentTintColor.c_str()];
154
+ } else {
155
+ _view.selectedSegmentTintColor = nil;
156
+ }
157
+ }
158
+
159
+ [super updateProps:props oldProps:oldProps];
160
+
161
+ // Update measurements when props change that affect layout
162
+ [self updateMeasurements];
163
+ }
164
+
165
+ #pragma mark - State (Measuring)
166
+
167
+ - (void)updateState:(const State::Shared &)state
168
+ oldState:(const State::Shared &)oldState {
169
+ _state = std::static_pointer_cast<
170
+ const MeasuringPCSegmentedControlShadowNode::ConcreteState>(state);
171
+
172
+ if (oldState == nullptr) {
173
+ // First time: compute initial size.
174
+ [self updateMeasurements];
175
+ }
176
+
177
+ [super updateState:state oldState:oldState];
178
+ }
179
+
180
+ - (void)updateMeasurements {
181
+ if (_state == nullptr)
182
+ return;
183
+
184
+ // Use the real width Yoga gave us
185
+ const CGFloat w = self.bounds.size.width > 1 ? self.bounds.size.width : 320;
186
+
187
+ CGSize size = [_view sizeForLayoutWithConstrainedTo:CGSizeMake(w, 0)];
188
+
189
+ PCSegmentedControlStateFrameSize next;
190
+ next.frameSize = {(Float)size.width, (Float)size.height};
191
+ _state->updateState(std::move(next));
192
+ }
193
+
194
+ @end