Skip to content

Conversation

@dnicolson
Copy link
Contributor

@dnicolson dnicolson commented Nov 29, 2025

User description

What does this PR do

This adjusts the navigation bar item and search bar placement to fix iPadOS 26 layout issues.

Any background context you want to provide

When built against the iOS 26 SDK, the search bar moves to the bottom on iOS but causes layout issues on iPadOS.

Screenshots (important for UI changes)

iPadOS Before iPadOS After
IMG_0091
IMG_0092
IMG_0093
macOS Before macOS After
Screenshot 2025-11-29 at 09 36 38
Screenshot 2025-11-29 at 09 36 10
Screenshot 2025-11-29 at 09 36 53
iOS Before iOS After
IMG_2115 IMG_2116

PR Type

Bug fix


Description

  • Fixes search bar layout issues on iOS 26 SDK

  • Implements platform-specific navigation bar handling

  • Uses stacked search bar placement for iOS 26+

  • Preserves legacy navigation bar styling for older versions


Diagram Walkthrough

flowchart LR
  A["iOS 26+ Detection"] --> B["Use titleView with imageView"]
  A --> C["Set stacked search bar placement"]
  D["Pre-iOS 26"] --> E["Apply tint to logo image"]
  D --> F["Set leftBarButtonItem with logo"]
  D --> G["Configure tint colors"]
Loading

File Walkthrough

Relevant files
Bug fix
SideMenuView.swift
Add iOS 26 conditional navigation bar handling                     

PVUI/Sources/PVSwiftUI/SideMenu/SideMenuView.swift

  • Added iOS 26 availability check to conditionally handle navigation bar
    setup
  • For iOS 26+: uses titleView with UIImageView and sets
    preferredSearchBarPlacement to .stacked
  • For pre-iOS 26: preserves existing logic with tinted logo image and
    leftBarButtonItem configuration
  • Refactored navigation bar customization into version-specific branches
+15/-10 

@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
No auditing: The new navigation/title/search bar configuration adds UI state changes without any
accompanying audit logging of critical actions, though this UI context may not require
audit trails.

Referred Code
if #available(iOS 26.0, *) {
    let imageView = UIImageView(image: image)
    vc.navigationItem.titleView = imageView
    vc.navigationItem.preferredSearchBarPlacement = .stacked
} else {
    let menuIconTint = themeManager.currentPalette.menuIconTint

    if menuIconTint != .clear {
            image?.applyTintEffectWithColor(menuIconTint)
    }
    let provenanceLogo = UIBarButtonItem(image: image)
    provenanceLogo.tintColor = themeManager.currentPalette.menuIconTint
    vc.navigationItem.leftBarButtonItem = provenanceLogo
    vc.navigationItem.leftBarButtonItem?.tintColor = menuIconTint
    vc.navigationController?.navigationBar.tintColor = menuIconTint
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing guards: New code assumes image loading succeeds and that navigation components exist without
handling nil cases or providing fallback behavior.

Referred Code
let image = UIImage(named: "provnavicon", in: PVUIBase.BundleLoader.myBundle, with: nil)
if #available(iOS 26.0, *) {
    let imageView = UIImageView(image: image)
    vc.navigationItem.titleView = imageView
    vc.navigationItem.preferredSearchBarPlacement = .stacked
} else {
    let menuIconTint = themeManager.currentPalette.menuIconTint

    if menuIconTint != .clear {
            image?.applyTintEffectWithColor(menuIconTint)
    }
    let provenanceLogo = UIBarButtonItem(image: image)
    provenanceLogo.tintColor = themeManager.currentPalette.menuIconTint
    vc.navigationItem.leftBarButtonItem = provenanceLogo
    vc.navigationItem.leftBarButtonItem?.tintColor = menuIconTint
    vc.navigationController?.navigationBar.tintColor = menuIconTint
}

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Consider platform-specific code for UI

Add a device-specific check (UIDevice.current.userInterfaceIdiom == .pad) to the
existing iOS version check. This will ensure the new navigation bar layout is
applied only to iPadOS, preserving the original layout on iPhones.

Examples:

PVUI/Sources/PVSwiftUI/SideMenu/SideMenuView.swift [410-425]
            if #available(iOS 26.0, *) {
                let imageView = UIImageView(image: image)
                vc.navigationItem.titleView = imageView
                vc.navigationItem.preferredSearchBarPlacement = .stacked
            } else {
                let menuIconTint = themeManager.currentPalette.menuIconTint

                if menuIconTint != .clear {
                        image?.applyTintEffectWithColor(menuIconTint)
                }

 ... (clipped 6 lines)

Solution Walkthrough:

Before:

.introspectViewController(customize: { vc in
    let image = UIImage(named: "provnavicon", ...)

    if #available(iOS 26.0, *) {
        // This block applies to both iPhone and iPad on iOS 26+
        let imageView = UIImageView(image: image)
        vc.navigationItem.titleView = imageView
        vc.navigationItem.preferredSearchBarPlacement = .stacked
    } else {
        // Legacy code for older iOS versions
        let provenanceLogo = UIBarButtonItem(image: image)
        vc.navigationItem.leftBarButtonItem = provenanceLogo
        ...
    }
})

After:

.introspectViewController(customize: { vc in
    let image = UIImage(named: "provnavicon", ...)

    // Check for both iOS version and device type (idiom)
    if #available(iOS 26.0, *), UIDevice.current.userInterfaceIdiom == .pad {
        // This block now only applies to iPad on iOS 26+
        let imageView = UIImageView(image: image)
        vc.navigationItem.titleView = imageView
        vc.navigationItem.preferredSearchBarPlacement = .stacked
    } else {
        // Legacy code used for iPhones and older iOS versions
        let provenanceLogo = UIBarButtonItem(image: image)
        vc.navigationItem.leftBarButtonItem = provenanceLogo
        ...
    }
})
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that a fix intended for iPadOS introduces a significant UI change on iPhone, and proposes a valid platform-specific check to decouple the behaviors, which is a critical design consideration.

Medium
Possible issue
Apply missing theme tint color

Move the icon tinting logic before the if #available block to ensure it's
applied consistently across all iOS versions, fixing a missing tint on iOS 26+.

PVUI/Sources/PVSwiftUI/SideMenu/SideMenuView.swift [410-414]

+let menuIconTint = themeManager.currentPalette.menuIconTint
+if menuIconTint != .clear {
+    image?.applyTintEffectWithColor(menuIconTint)
+}
+
 if #available(iOS 26.0, *) {
     let imageView = UIImageView(image: image)
     vc.navigationItem.titleView = imageView
     vc.navigationItem.preferredSearchBarPlacement = .stacked
 } else {
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a visual bug where the navigation icon tint is not applied on iOS 26+, and the proposed fix correctly resolves this inconsistency.

Medium
General
Prevent navigation icon distortion

Set the contentMode of the UIImageView to .scaleAspectFit to prevent the
navigation icon from being distorted.

PVUI/Sources/PVSwiftUI/SideMenu/SideMenuView.swift [411-412]

 let imageView = UIImageView(image: image)
+imageView.contentMode = .scaleAspectFit
 vc.navigationItem.titleView = imageView
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion improves UI robustness by setting the contentMode on the UIImageView, which is a good practice to prevent potential image distortion in the navigation bar.

Low
  • More

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant