@craft-native/ios 0.0.481 → 0.0.483
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/package.json
CHANGED
|
@@ -3155,6 +3155,44 @@ private class CraftNativeFlowView: UIStackView {
|
|
|
3155
3155
|
|
|
3156
3156
|
// MARK: Touches
|
|
3157
3157
|
|
|
3158
|
+
/// UIKit skips empty component wrappers, including their visible floating
|
|
3159
|
+
/// controls. Supply the real accessible descendants only when such wrappers
|
|
3160
|
+
/// occur; ordinary native subtrees keep UIKit's automatic traversal.
|
|
3161
|
+
private var authoredAccessibilityElements: [Any]?
|
|
3162
|
+
private weak var explicitAccessibilityOwner: CraftNativeFlowView?
|
|
3163
|
+
private var needsExplicitAccessibility: Bool {
|
|
3164
|
+
if let owner = explicitAccessibilityOwner, isDescendant(of: owner), owner.needsExplicitAccessibility { return true }
|
|
3165
|
+
return subviews.contains(where: { $0 is CraftNativeFlowView && $0.bounds.isEmpty })
|
|
3166
|
+
}
|
|
3167
|
+
override var accessibilityElements: [Any]? {
|
|
3168
|
+
get {
|
|
3169
|
+
if let authored = authoredAccessibilityElements { return authored }
|
|
3170
|
+
guard !isAccessibilityElement, needsExplicitAccessibility else { return nil }
|
|
3171
|
+
return subviews.flatMap { Self.accessibleDescendants($0, owner: self) }
|
|
3172
|
+
}
|
|
3173
|
+
set {
|
|
3174
|
+
authoredAccessibilityElements = newValue
|
|
3175
|
+
super.accessibilityElements = newValue
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
|
|
3179
|
+
private static func accessibleDescendants(_ view: UIView, owner: CraftNativeFlowView) -> [Any] {
|
|
3180
|
+
guard !view.isHidden, view.alpha > 0.01, !view.accessibilityElementsHidden else { return [] }
|
|
3181
|
+
guard let flow = view as? CraftNativeFlowView, !flow.isAccessibilityElement,
|
|
3182
|
+
flow.accessibilityContainerType == .none else { return [view] }
|
|
3183
|
+
guard !flow.bounds.isEmpty || !flow.clipsToBounds else { return [] }
|
|
3184
|
+
if let authored = flow.authoredAccessibilityElements { return authored }
|
|
3185
|
+
if !flow.bounds.isEmpty {
|
|
3186
|
+
// Keep the real container's identity and frame, and let UIKit
|
|
3187
|
+
// traverse its real children through the same explicit contract.
|
|
3188
|
+
// Flattening every nonempty View discarded ordinary containers
|
|
3189
|
+
// such as the native navigation fixture's max-content bubble.
|
|
3190
|
+
flow.explicitAccessibilityOwner = owner
|
|
3191
|
+
return [flow]
|
|
3192
|
+
}
|
|
3193
|
+
return flow.subviews.flatMap { accessibleDescendants($0, owner: owner) }
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3158
3196
|
/// A child drawn outside this view's bounds still takes its touches, as an
|
|
3159
3197
|
/// overflowing element is clickable on the web, unless the view clips
|
|
3160
3198
|
/// (`overflow: hidden`). UIKit only asks a view's children when the point
|
|
@@ -4414,6 +4452,9 @@ private final class CraftNativeSegmentedControl: UISegmentedControl {
|
|
|
4414
4452
|
if segments.count != items.count { segments = items.indices.map { CraftNativeSegmentElement(control: self, index: $0) } }
|
|
4415
4453
|
for (index, item) in items.enumerated() {
|
|
4416
4454
|
segments[index].accessibilityLabel = item["spoken"] as? String ?? item["label"] as? String ?? values[index]
|
|
4455
|
+
// Match the shared component's <group testID>-<value> identity.
|
|
4456
|
+
// UIKit's private segment views do not inherit identifiers.
|
|
4457
|
+
segments[index].accessibilityIdentifier = accessibilityIdentifier.map { "\($0)-\(values[index])" }
|
|
4417
4458
|
}
|
|
4418
4459
|
refreshAccessibilityState()
|
|
4419
4460
|
setNeedsLayout()
|
|
@@ -7984,8 +8025,15 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7984
8025
|
func styled(_ base: UINavigationBarAppearance) -> UINavigationBarAppearance {
|
|
7985
8026
|
let appearance = UINavigationBarAppearance(barAppearance: base)
|
|
7986
8027
|
if navigationBarSolid {
|
|
7987
|
-
|
|
7988
|
-
|
|
8028
|
+
// iOS 26 places the expanded title in the scroll content.
|
|
8029
|
+
// An opaque bar covers it. The hard scroll-edge effect below
|
|
8030
|
+
// supplies the system's solid backdrop without hiding the title.
|
|
8031
|
+
if #available(iOS 26.0, *) {
|
|
8032
|
+
appearance.configureWithTransparentBackground()
|
|
8033
|
+
} else {
|
|
8034
|
+
appearance.configureWithOpaqueBackground()
|
|
8035
|
+
appearance.backgroundColor = screenBackgroundColor ?? config.resolvedBackgroundColor
|
|
8036
|
+
}
|
|
7989
8037
|
appearance.shadowColor = .clear
|
|
7990
8038
|
}
|
|
7991
8039
|
CraftChromeFonts.apply(to: appearance)
|
|
@@ -8285,12 +8333,12 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
8285
8333
|
}
|
|
8286
8334
|
#if compiler(>=6.2)
|
|
8287
8335
|
if #available(iOS 26.0, *) {
|
|
8288
|
-
//
|
|
8289
|
-
//
|
|
8290
|
-
//
|
|
8291
|
-
//
|
|
8336
|
+
// UIKit composites its expanded title with the scroll content on
|
|
8337
|
+
// iOS 26. Use the native hard edge for solid navigation chrome;
|
|
8338
|
+
// an opaque UINavigationBarAppearance would cover that title.
|
|
8339
|
+
// The floating tab pill already carries its own material.
|
|
8292
8340
|
scroll?.topEdgeEffect.isHidden = false
|
|
8293
|
-
scroll?.topEdgeEffect.style = topEdgeToEdge
|
|
8341
|
+
scroll?.topEdgeEffect.style = topEdgeToEdge ? (navigationBarSolid ? .hard : .soft) : .automatic
|
|
8294
8342
|
scroll?.bottomEdgeEffect.isHidden = tabbedScroll
|
|
8295
8343
|
}
|
|
8296
8344
|
#endif
|