@craft-native/ios 0.0.475 → 0.0.476

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/README.md CHANGED
@@ -342,6 +342,11 @@ needs a solid bar.
342
342
  The `backgroundColor` navigation option is shared with the Android native host;
343
343
  omitting it or passing `null` returns to the app's dynamic light/dark colour.
344
344
 
345
+ Set `titleColor` to a screen's text colour when its branded palette needs a
346
+ different navigation title contrast. Both native hosts apply it to inline and
347
+ large titles. Passing `null` restores the host's normal title colour; it does
348
+ not change the bar material, button colours, or another screen's appearance.
349
+
345
350
  The optional Liquid Glass tab-bar styling is compiler-gated for Xcode 26/Swift 6.2 and later. Older SDKs compile the same tab bar with the material fallback, so generated projects remain buildable on Xcode 16.
346
351
 
347
352
  The iOS host overlays `craft.config.json` on its defaults. Missing or `null` capability flags stay disabled; explicitly set a flag to `true` to enable it. Both the Swift host and Zig bridge reject malformed values and fall back to all capabilities disabled.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craft-native/ios",
3
- "version": "0.0.475",
3
+ "version": "0.0.476",
4
4
  "homepage": "https://github.com/craft-native/craft/tree/main/packages/ios#readme",
5
5
  "repository": {
6
6
  "type": "git",
@@ -7856,6 +7856,8 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
7856
7856
  /// the home indicator too, where its content never reaches: a black
7857
7857
  /// full-screen timer is black edge to edge. nil is the app's.
7858
7858
  private var screenBackgroundColor: UIColor?
7859
+ /// Title contrast belongs to this screen, independently of the bar material.
7860
+ private var navigationTitleColor: UIColor?
7859
7861
 
7860
7862
  override var preferredStatusBarStyle: UIStatusBarStyle {
7861
7863
  statusBarStyleOverride ?? .default
@@ -7926,6 +7928,9 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
7926
7928
  if let solid = options["navigationBarSolid"] as? Bool {
7927
7929
  navigationBarSolid = solid
7928
7930
  }
7931
+ if options.keys.contains("titleColor") {
7932
+ navigationTitleColor = color(options["titleColor"])
7933
+ }
7929
7934
  if let hidden = options["hidden"] as? Bool {
7930
7935
  navigationBarHidden = hidden
7931
7936
  if navigationController?.topViewController === self {
@@ -7941,7 +7946,7 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
7941
7946
  let buttons = (options["rightButtons"] as? [[String: Any]]) ?? []
7942
7947
  navigationItem.rightBarButtonItems = buttons.compactMap(navigationButton).reversed()
7943
7948
  }
7944
- if options.keys.contains("backgroundColor") || options.keys.contains("navigationBarSolid") {
7949
+ if options.keys.contains("backgroundColor") || options.keys.contains("navigationBarSolid") || options.keys.contains("titleColor") {
7945
7950
  applyNavigationBarAppearance()
7946
7951
  trackContentScrollView()
7947
7952
  }
@@ -7952,25 +7957,44 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
7952
7957
  }
7953
7958
  }
7954
7959
 
7955
- /// Applies the screen's optional opaque bar without changing the default
7956
- /// UIKit material when the screen did not opt in.
7960
+ /// Per-item appearances preserve each UIKit bar state and never recolour a
7961
+ /// sibling controller's title or opt a material bar into an opaque fill.
7957
7962
  private func applyNavigationBarAppearance() {
7958
- guard navigationBarSolid else {
7963
+ guard navigationBarSolid || navigationTitleColor != nil else {
7959
7964
  navigationItem.standardAppearance = nil
7960
7965
  navigationItem.scrollEdgeAppearance = nil
7961
7966
  navigationItem.compactAppearance = nil
7962
7967
  navigationItem.compactScrollEdgeAppearance = nil
7963
7968
  return
7964
7969
  }
7965
- let appearance = UINavigationBarAppearance()
7966
- appearance.configureWithOpaqueBackground()
7967
- appearance.backgroundColor = screenBackgroundColor ?? config.resolvedBackgroundColor
7968
- appearance.shadowColor = .clear
7969
- CraftChromeFonts.apply(to: appearance)
7970
- navigationItem.standardAppearance = appearance
7971
- navigationItem.scrollEdgeAppearance = appearance
7972
- navigationItem.compactAppearance = appearance
7973
- navigationItem.compactScrollEdgeAppearance = appearance
7970
+ let bar = navigationController?.navigationBar
7971
+ let standard = bar?.standardAppearance ?? UINavigationBarAppearance()
7972
+ // UIKit's unspecified scroll-edge appearance uses a transparent
7973
+ // background. Copy its standard text/button attributes before applying
7974
+ // that background so adding title contrast preserves the same states.
7975
+ let scrollEdge = bar?.scrollEdgeAppearance ?? {
7976
+ let appearance = UINavigationBarAppearance(barAppearance: standard)
7977
+ appearance.configureWithTransparentBackground()
7978
+ return appearance
7979
+ }()
7980
+ func styled(_ base: UINavigationBarAppearance) -> UINavigationBarAppearance {
7981
+ let appearance = UINavigationBarAppearance(barAppearance: base)
7982
+ if navigationBarSolid {
7983
+ appearance.configureWithOpaqueBackground()
7984
+ appearance.backgroundColor = screenBackgroundColor ?? config.resolvedBackgroundColor
7985
+ appearance.shadowColor = .clear
7986
+ }
7987
+ CraftChromeFonts.apply(to: appearance)
7988
+ if let navigationTitleColor {
7989
+ appearance.titleTextAttributes[.foregroundColor] = navigationTitleColor
7990
+ appearance.largeTitleTextAttributes[.foregroundColor] = navigationTitleColor
7991
+ }
7992
+ return appearance
7993
+ }
7994
+ navigationItem.standardAppearance = styled(standard)
7995
+ navigationItem.scrollEdgeAppearance = styled(scrollEdge)
7996
+ navigationItem.compactAppearance = styled(bar?.compactAppearance ?? standard)
7997
+ navigationItem.compactScrollEdgeAppearance = styled(bar?.compactScrollEdgeAppearance ?? scrollEdge)
7974
7998
  }
7975
7999
 
7976
8000
  private func applyStatusBar(_ props: [String: Any]) {