Skip to content

✨ [iOS] Native toolbar#51

Draft
MatuskaDev wants to merge 6 commits into
feature/an/navigation3from
feature/ios/native-toolbar
Draft

✨ [iOS] Native toolbar#51
MatuskaDev wants to merge 6 commits into
feature/an/navigation3from
feature/ios/native-toolbar

Conversation

@MatuskaDev

Copy link
Copy Markdown
Contributor

📝 Description

💡 What’s new?

  • Introduced new Toolbar data model which defines the toolbar appearance. The Toolbar is defined and set in view's view model - it cannot be set in Compose as the toolbar needs to be set on iOS before the first composition & directly in SwiftUI not nested inside a controller.

😶 What’s missing?

  • FIXME

📚 References

  • FIXME

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e6ff151b-0ccf-4ccb-86a8-26e60299971d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ios/native-toolbar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MatuskaDev MatuskaDev changed the title Feature/ios/native toolbar ✨ [iOS] Native toolbar Apr 20, 2026
@MatuskaDev MatuskaDev requested review from Copilot and tomas-bat April 20, 2026 08:17

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a cross-platform NativeScaffold and Toolbar system, incorporating the haze library for UI effects and refactoring SampleFeature. Feedback identifies a typo in an iOS availability check and behavioral inconsistencies in back button handling. Recommendations include optimizing Android performance by remembering filtered lists, improving accessibility with larger touch targets, and ensuring design consistency by adhering to theme-defined typography and Material 3 Icon standards. Additionally, simplifying the NativeColor model was suggested.

Comment thread ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/View+Toolbar.swift Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a cross-platform Toolbar model and NativeScaffold abstraction so Kotlin view models can drive a native iOS navigation bar (title/buttons/menus + Liquid Glass styling) while keeping Android on a Compose TopAppBar implementation.

Changes:

  • Introduces Toolbar + NativeScaffold (expect/actual) and wires BaseScopedViewModel to expose toolbar: StateFlow<Toolbar?>.
  • Refactors SampleFeature to use a new SampleFeatureRoute that binds state/events/toolbar consistently across iOS and Android.
  • Adds iOS SwiftUI toolbar binding utilities and updates Xcode scripts / build logic dependencies for the new UI stack.

Reviewed changes

Copilot reviewed 32 out of 38 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
shared/samplefeature/src/iosMain/kotlin/kmp/shared/samplefeature/presentation/SampleFeatureMainScreenViewController.kt Switches iOS entry VC to SampleFeatureRoute and adds onShowMessage hook.
shared/samplefeature/src/commonMain/kotlin/kmp/shared/samplefeature/presentation/vm/SampleFeatureViewModel.kt Adds getToolbar() override to provide title/logo from MR resources.
shared/samplefeature/src/commonMain/kotlin/kmp/shared/samplefeature/presentation/ui/SampleFeatureRoute.kt New route composable wiring state, toolbar, and event-driven message handling.
shared/samplefeature/src/commonMain/kotlin/kmp/shared/samplefeature/presentation/ui/SampleFeatureMainScreen.kt Wraps content in NativeScaffold and threads Toolbar? into UI.
shared/base/src/iosMain/kotlin/kmp/shared/base/presentation/vm/BaseScopedViewModel.ios.kt Exposes toolbar StateFlow via Molecule on iOS.
shared/base/src/iosMain/kotlin/kmp/shared/base/presentation/ui/NativeScaffold.kt iOS NativeScaffold actual: Compose Scaffold + optional blur container.
shared/base/src/iosMain/kotlin/kmp/shared/base/presentation/ui/NativeColor.kt iOS bridge to convert NativeColor to UIColor.
shared/base/src/iosMain/kotlin/kmp/shared/base/presentation/ui/Keyboard.ios.kt iOS implementations for keyboard dismissal/focus behaviors.
shared/base/src/iosMain/kotlin/kmp/shared/base/presentation/ui/BlurredContainer.kt New blurred container using Haze + gradients for iOS styling.
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-light@3x.png Adds toolbar brand logo asset (light, 3x).
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-light@2x.png Adds toolbar brand logo asset (light, 2x).
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-light@1x.png Adds toolbar brand logo asset (light, 1x).
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-dark@3x.png Adds toolbar brand logo asset (dark, 3x).
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-dark@2x.png Adds toolbar brand logo asset (dark, 2x).
shared/base/src/commonMain/moko-resources/images/toolbar_brand_logo-dark@1x.png Adds toolbar brand logo asset (dark, 1x).
shared/base/src/commonMain/kotlin/kmp/shared/base/presentation/vm/BaseScopedViewModel.kt Adds toolbar flow to base VM contract and getToolbar() hook.
shared/base/src/commonMain/kotlin/kmp/shared/base/presentation/ui/Toolbar.kt New Toolbar/button/menu model shared across platforms.
shared/base/src/commonMain/kotlin/kmp/shared/base/presentation/ui/NativeScaffold.kt New expect declaration for platform-native scaffold.
shared/base/src/commonMain/kotlin/kmp/shared/base/presentation/ui/Keyboard.kt New expect keyboard-related modifier APIs.
shared/base/src/androidMain/res/drawable/ic_back_arrow.xml Adds Android back arrow vector asset for toolbar back button.
shared/base/src/androidMain/kotlin/kmp/shared/base/presentation/vm/BaseScopedViewModel.android.kt Exposes toolbar StateFlow via Molecule on Android.
shared/base/src/androidMain/kotlin/kmp/shared/base/presentation/ui/NativeScaffold.kt Android NativeScaffold actual with Material3 TopAppBar + buttons/menus + Haze.
shared/base/src/androidMain/kotlin/kmp/shared/base/presentation/ui/Keyboard.android.kt Android implementations for keyboard modifiers (IME scroll/focus).
shared/base/src/androidMain/kotlin/kmp/shared/base/presentation/ui/HazeTextButton.kt Adds Haze-styled text button used in transparent toolbar.
shared/base/src/androidMain/kotlin/kmp/shared/base/presentation/ui/HazeIconButton.kt Adds Haze-styled icon button used in transparent toolbar.
ios/scripts/generate-strings.sh Skips MR generation during Xcode clean.
ios/scripts/build-kmp.sh Runs Gradle clean during Xcode clean; keeps embed/sign for builds.
ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/View+Toolbar.swift New SwiftUI extension to apply KMP Toolbar to native nav bar/toolbars.
ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/View+NavigationBarTitleColor.swift New helper to set nav bar title color via a representable VC.
ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/View+Extensions.swift Changes bindViewModel to bind toolbar updates and clear VM scope on dismiss.
ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/Moko+Extensions.swift Adds SwiftUI Image init for ImageResource and StringDesc localization helper.
ios/PresentationLayer/SampleFeature/Sources/SampleFeature/SampleFeatureView.swift Wires toast handling via onShowMessage, binds VM toolbar, updates DI wrapper usage.
ios/DomainLayer/SharedDomain/Sources/SharedDomain/ViewModels+Extensions.swift Retroactive ObservableObject conformance for SampleFeatureViewModel.
ios/Application/AppDelegate.swift Removes global navigation bar appearance setup (defers to per-screen toolbar).
ios/.swiftlint.yml Excludes SharedDomain build output from SwiftLint scanning.
gradle/libs.versions.toml Adds Haze deps + adjusts Compose version to match Haze support.
build-logic/convention/src/main/kotlin/plugin/KmpLibraryComposeConventionPlugin.kt Adds moko-resources compose + haze deps to the Compose convention plugin.
android/samplefeature/src/main/kotlin/kmp/android/samplefeature/ui/SampleFeatureMain.kt Refactors Android route to use SampleFeatureRoute + toast callback.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ios/PresentationLayer/UIToolkit/Sources/UIToolkit/Extensions/View+Toolbar.swift Outdated
Comment thread shared/base/src/commonMain/kotlin/kmp/shared/base/presentation/ui/Toolbar.kt Outdated
^ Conflicts:
^	android/samplefeature/src/main/kotlin/kmp/android/samplefeature/ui/SampleFeatureMain.kt
^	build-logic/convention/src/main/kotlin/plugin/KmpLibraryComposeConventionPlugin.kt
^	gradle/libs.versions.toml
^	ios/.swiftlint.yml
^	shared/samplefeature/src/iosMain/kotlin/kmp/shared/samplefeature/presentation/SampleFeatureMainScreenViewController.kt
@MatuskaDev MatuskaDev force-pushed the feature/ios/native-toolbar branch from 3c34a94 to 3fb41a6 Compare April 20, 2026 08:32
Comment on lines +13 to +17
ComposeUIViewController {
SampleFeatureRoute(
viewModel = viewModel,
onShowMessage = onShowMessage,
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, we now reuse shared routes even with native navigation? 🤔

Since that onSubscription block of SampleFeatureRoutes vm events handles onAppear, won't it cause that it will only be called on the initial appear?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants