Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting navigationBarTitleDisplayMode doesn't work for modal routing. #71

Open
polszacki-tooploox opened this issue Jun 2, 2022 · 6 comments

Comments

@polszacki-tooploox
Copy link

When presenting a modal view using router.route(to: \.newCall) the navigation title is always displayed as .large even though the view has .navigationBarTitleDisplayMode set to .inline. It doesn't happen when the same view is presented using standard SwiftUI .sheet.

iPhone

View presented with router.route(to: \.newCall): View presented with .sheet:
Simulator Screen Shot - iPhone 13 Pro - 2022-06-02 at 13 32 22 Simulator Screen Shot - iPhone 13 Pro - 2022-06-02 at 13 32 20

Code from the parent view and the coordinator:

struct TestView: View {
	@State var isPresented = false
	@EnvironmentObject private var router: TestCoordinator.Router

	var body: some View {
		VStack {
			Spacer()
			Button("Test sheet") { isPresented.toggle() }
				.sheet(isPresented: $isPresented, content: {
					NavigationView {
						NewCallView()
							.navigationTitle("New call")
							.navigationBarTitleDisplayMode(.inline)
					}
				})
			Spacer()
			Button("Test Stinsen") {
				router.route(to: \.newCall)
			}
			Spacer()
		}
	}
}


final class TestCoordinator: NavigationCoordinatable { 
    (...)
		@Route(.modal) var newCall = makeNewCallView

		@ViewBuilder
		func makeNewCallView() -> some View {
			NavigationView {
				NewCallView()
					.navigationTitle("New call")
					.navigationBarTitleDisplayMode(.inline)
			}
		}
    }
}
@rundfunk47
Copy link
Owner

Hi, there is a branch that might solve this issue: navbarless. Could you please test it out and see if it works? I'm not 100% done with it yet, so I haven't merged it...

@polszacki-tooploox
Copy link
Author

Thanks for the reply. It works on the navbarless branch.

@polszacki-tooploox
Copy link
Author

Do you have any ETA on the branch to be merged in or at least stable for production?

@rundfunk47
Copy link
Owner

There are still some bugs left to fix (try for instance presenting a modal screen and then pushing a new one), I'll look into it this week and hopefully fix it.

@LePips
Copy link
Collaborator

LePips commented Jun 28, 2022

To work with the current state of Stinsen (and how I think it should properly be), instead of creating an explicit NavigationView to present, return a NavigationViewCoordinator<NewCallCoordinator>. This will require creating a new NewCallCoordinator that conforms to NavigationCoordinatable and might just have a single view but this pattern has worked for me for a long time.

Change from your example to:

final class TestCoordinator: NavigationCoordinatable { 
    (...)
    @Route(.modal) var newCall = makeNewCallView

    func makeNewCallView() -> NavigationViewCoordinator<NewCallCoordinator> {
        NavigationViewCoordinator(NewCallCoordinator())
    }
}

and create:

final class NewCallCoordinator: NavigationCoordinatable {

    let stack = NavigationStack(initial: \NewCallCoordinator.start)

    @Root
    var start = makeStart

    @ViewBuilder
    func makeStart() -> some View {
        Text("Hello There")
            .navigationBarTitleDisplayMode(.inline) // This will be inlined
            .navigationTitle("Inline Me")
    }
}

Names are just used for examples. I have used this pattern ever since I used Stinsen as I feel it's how its supposed to work by handling the NavigationView creation to our coordinator pattern. We shouldn't have to create our own NavigationView at all. This does increase some code boilerplate and files but conforms to the pattern a lot better and makes view creation and routing more declarative.

@rundfunk47
Copy link
Owner

rundfunk47 commented Jun 28, 2022

I agree here. Modally presenting a NavigationView is not really the "Stinsen"-esque way. Usually you'd want to present a Coordinator here. This might be a bit tricky to fix since Stinsen needs to "inject" it's navigation-logic inside the view presented by the NavigationView, not the navigationview itself... I haven't had time to look for an alternative solution yet, but this is probably the top priority issue I want to attempt to fix at least.

But as @LePips says, there are workarounds that are "better".

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

No branches or pull requests

3 participants