GetStream / stream-chat-swiftui

SwiftUI Chat SDK ➜ Stream Chat 💬
https://getstream.io/chat/sdk/swiftui/
Other
348 stars 87 forks source link

How to hide TabView bottom toolbar when ChatChannelView is pushed? #27

Closed linhewinner closed 2 years ago

linhewinner commented 2 years ago

What are you trying to achieve?

I want to achieve WhatsApp-style navigation where I have a TabView for the top-level navigation of the app, but when ChatChannelView is pushed, the bottom toolbar is hidden.

What I initially tried:

TabView {
   HomeView()
   ChatChannelListView() // <--- This has a NavigationView inside
}

Now when I tap on a thread, the ChatChannelView is nested inside the TabView. So the TextField input is not at the bottom of the screen but rather nested inside the TabView.

In UIKit, there is hidesBottomBarWhenPushed to configure this, but there doesn't appear to be an obvious way to do so in SwiftUI?

Next I tried this:

NavigationView {
  TabView {
    HomeView()
    ChatChannelListViewWithoutNavigation() // <=== by copy-pasting ChatChannelListView and editing it
  }
}

This could work but it would be nice if ChatChannelListView allows me to customize it without copy-pasting? In this setup, there also appears to be a nasty SwiftUI bug on iOS 15 where if you background the app, the ChatChannelView automatically gets popped ....

If possible, how can you achieve this currently?

Right now, I am copy-pasting ChannelListView into CustomChannelListView and modifying the file to get rid of the NavigationView. Ideally, StreamChatSwiftUI SDK should let me customize that ...

What would be the better way?

See above

martinmitrevski commented 2 years ago

Hi @linhewinner,

The recommended approach for structuring a tab-based iOS app is to have the TabView as the root view, with separate NavigationViews for the corresponding views inside. The other way around (having a root navigation view and a tab view inside), is not recommended.

Several sources on the topic:

The current SDK setup supports TabView and the WhatsApp style by following this pattern.

If you still need to go with your own NavigationView, then you can directly use our ChatChannelList component and our ChatChannelListViewModel, which is basically what you've already started doing.

Hope this helps, Martin

linhewinner commented 2 years ago

@martinmitrevski Let's say we have NavigationView nested inside TabView like Apple recommends (which I did in the past with UIKit) ...

To implement WhatsApp-style navigation, you need hidesBottomBarWhenPushed otherwise the composer is nested above the TabBar bottom toolbar: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621863-hidesbottombarwhenpushed

I don't see anything like hidesBottomBarWhenPushed in SwiftUI, do you? Do you have any recommendations for hiding the TabBar bottom toolbar when the ChatChannelView is pushed?

martinmitrevski commented 2 years ago

@linhewinner Sorry, now I get what you are trying to achieve. I'll reopen this to check it there's a feasible way to do this in SwiftUI.

linhewinner commented 2 years ago

Sorry I didn't make it clear from get-go. I updated my issue title and comment details to reflect a clearer description of my goals

martinmitrevski commented 2 years ago

@linhewinner an update about the issue:

I'll keep this open for you to test it out and provide some feedback.

linhewinner commented 2 years ago

@martinmitrevski I appreciate the fast turn-around.

I too made it work with some UIKit trickery ... many factors considered, our team decided to use Stream's UIKit SDK instead. So I am unlikely to return to this and test. But I appreciate that the Stream team is so responsive and I don't regret my choice of Stream :)

martinmitrevski commented 2 years ago

Ok, thanks for your feedback and the reported issues. I'm closing the issue.

rocxteady commented 2 years ago

You are talking about some tricker stuff but neither of you mentioned what you did exactly to solve this. :(

martinmitrevski commented 2 years ago

Hey @rocxteady, this is part of the SDK - you don't need to do anything additional to hide the tabbar when the channel view is pushed. If you're curious about how it works, please check the code that deals with this: https://github.com/GetStream/stream-chat-swiftui/blob/c9c260f9887fe720cc6e2068d3dffef872597952/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift#L110. Best, Martin

rocxteady commented 2 years ago

It's not working for me using like this:

NavigationLink {
    ChatChannelView(viewFactory: UniViewFactory.shared, channelController: try! chatClient.channelController(createDirectMessageChannelWith: .init(arrayLiteral: match.profile.user?.username ?? "", UniUser.current?.username ?? ""), extraData: [:]))
} label: {
    MatchItemView(match: match)
}
martinmitrevski commented 2 years ago

@rocxteady, if you're using only the ChatChannelView, you would need to implement the hide tabbar logic by yourself in your hosting view. Check the implementation in our ChatChannelListView, that deals with the tabbar (that I've linked above).

rocxteady commented 2 years ago

Thank you. @martinmitrevski