Skip to content

Commit 3b1ec3d

Browse files
authored
Implemented changes in ChannelHeader article (#110)
1 parent c9f0990 commit 3b1ec3d

File tree

6 files changed

+85
-47
lines changed

6 files changed

+85
-47
lines changed
297 KB
Loading
500 KB
Loading
306 KB
Loading
277 KB
Loading
281 KB
Loading

docusaurus/docs/iOS/swiftui/components/channel-header.md

Lines changed: 85 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,29 @@
22
title: Channel Header
33
---
44

5+
## What is the Channel Header?
6+
7+
![Depiction of the channel header.](../../assets/channel-header-swiftui.png)
8+
9+
The channel header appears at the top of the list of messages. It serves the purpose of displaying the name of the channel (top line) as well as additional information (bottom line).
10+
11+
In addition to that it can offer buttons on the trailing edge (here: right). They can server different purposes, such as showing additional information about the channel, or other custom actions.
12+
513
## Customizing the Channel Header
614

7-
In most cases, you will need to customize the channel header to fit in with the rest of your app. The SwiftUI SDK provides several customization options, from minor tweaks to ultimately providing your own header.
15+
You might want to customize the channel header to fit in with the rest of your app. The SwiftUI SDK provides several customization options, from minor tweaks to ultimately providing your own header.
16+
17+
For the customization you have 3 options:
18+
19+
1. the `ChatChannelNamer` in the `Utils` class that can be handed to `StreamChat` upon creation
20+
2. the `tintColor` in the `Appearance` class that can be handed to `StreamChat` upon creation
21+
3. creating your own header completely
822

9-
The most straightforward change you can do is to change the header's title while keeping the same look and feel of it. To do this, you need to provide your own implementation of the `ChannelNamer` protocol and inject it in the `Utils` class of the `StreamChat` context provider object.
23+
Each option servers different purposes, so here are examples for all of them.
24+
25+
### Customizing the name of the channel
26+
27+
You can change the header's title while keeping the same look and feel of it. To do this, you need to provide your own implementation of the `ChannelNamer` protocol and inject it in the `Utils` class of the `StreamChat` context provider object.
1028

1129
```swift
1230
let channelNamer: ChatChannelNamer = { channel, currentUserId in
@@ -17,6 +35,14 @@ let utils = Utils(channelNamer: channelNamer)
1735
let streamChat = StreamChat(chatClient: chatClient, utils: utils)
1836
```
1937

38+
Below you can see the comparison of the before and after of this change.
39+
40+
![Depiction of the channel header namer comparison.](../../assets/channel-header-namer.png)
41+
42+
> 💡 The best place to do this would be in the `AppDelegate` file of your project. Not sure how to set this one up? We got you covered in our [Getting started guide](../getting-started.md).
43+
44+
### Changing the color of the header
45+
2046
Another simple change you can do is to change the tint color of the header. This will change the navigation bar buttons in all of the SDK components. To do this, simply initialize the `StreamChat` object with your preferred tint color.
2147

2248
```swift
@@ -28,39 +54,32 @@ let appearance = Appearance(colors: colors)
2854
let streamChat = StreamChat(chatClient: chatClient, appearance: appearance)
2955
```
3056

31-
## Creating Your Own Header
57+
Below you can see the comparison of the before and after of this change.
3258

33-
In most cases, you will need to customize the navigation bar even further - either by adding branding information, like logo and text, or even additional buttons that will either push a new view, display a modal sheet or an alert.
59+
![Depiction of the channel header with different tint colors.](../../assets/channel-header-tint.png)
3460

35-
In order to do this, you will need to perform a few steps. First, you need to create your own header, conforming to SwiftUI's `ToolbarContent` protocol. Let's create a header that will show an additional button to the right, to do changes to the channel instead of the default avatar view.
61+
### Creating Your Own Header
3662

37-
```swift
38-
public struct CustomChatChannelHeader: ToolbarContent {
39-
@Injected(\.fonts) var fonts
40-
@Injected(\.utils) var utils
41-
@Injected(\.colors) var colors
42-
@Injected(\.chatClient) var chatClient
63+
There are cases where you want to customize the navigation bar even further - either by adding branding information, like logo and text, or even additional buttons that will either push a new view, display a modal sheet or an alert.
4364

44-
private var channelNamer: ChatChannelNamer {
45-
utils.channelNamer
46-
}
65+
In order to do this, you will need to perform four steps:
4766

48-
private var currentUserId: String {
49-
chatClient.currentUserId ?? ""
50-
}
67+
1. Create a header conforming to `ToolbarContent`
68+
2. Create a modifier conforming to `ChatChannelHeaderViewModifier`
69+
3. Override `makeChannelHeaderViewModifier` in a custom `ViewFactory`
70+
4. Inject the custom `ViewFactory` into the view hierarchy.
5171

52-
public var channel: ChatChannel
53-
public var onTapTrailing: () -> ()
72+
First, you need to create your own header, conforming to SwiftUI's `ToolbarContent` protocol. Let's create a header that will show an additional button to the right, to do changes to the channel instead of the default avatar view.
5473

55-
public var body: some ToolbarContent {
74+
```swift
75+
struct CustomChatChannelHeader: ToolbarContent {
76+
77+
var channelName: String
78+
var onTapTrailing: () -> ()
79+
80+
var body: some ToolbarContent {
5681
ToolbarItem(placement: .principal) {
57-
VStack {
58-
Text(channelNamer(channel, currentUserId) ?? "")
59-
.font(fonts.bodyBold)
60-
Text(channel.onlineInfoText(currentUserId: currentUserId))
61-
.font(fonts.footnote)
62-
.foregroundColor(Color(colors.textLowEmphasis))
63-
}
82+
Text(channelName)
6483
}
6584

6685
ToolbarItem(placement: .navigationBarTrailing) {
@@ -75,32 +94,31 @@ public struct CustomChatChannelHeader: ToolbarContent {
7594
}
7695
```
7796

78-
Our custom header implementation exposes an onTapTrailing callback, that will be called when the trailing button is tapped (for example for displaying an edit view). The implementation of this button will be done in a `ViewModifier`, since the `ToolbarContent` can't keep `@State` variables.
97+
The custom header implementation exposes an onTapTrailing callback, that will be called when the trailing button is tapped (e.g. for displaying an edit view). The implementation of this button will be done in a `ViewModifier`, since the `ToolbarContent` can't keep `@State` variables.
7998

80-
The next step is to provide a new implementation of the `ChatChannelHeaderViewModifier`. In our case, we need to provide handling for the onTapTrailing method from the `CustomChatChannelHeader`. To do this, we will introduce a new `@State` variable in the modifier and change its state to true when the button is tapped.
99+
The next step is to provide a new implementation of the `ChatChannelHeaderViewModifier`. In this case, you need to provide handling for the `onTapTrailing` method from the `CustomChatChannelHeader`. To do this, you introduce a new `@State` variable in the modifier and change its state to true when the button is tapped.
81100

82101
```swift
83-
struct CustomChannelModifier: ChatChannelHeaderViewModifier {
102+
struct CustomChatChannelModifier: ChatChannelHeaderViewModifier {
84103

104+
@State private var editShown = false
85105
var channel: ChatChannel
86106

87-
@State var editShown = false
88-
89107
func body(content: Content) -> some View {
90108
content.toolbar {
91-
CustomChatChannelHeader(channel: channel) {
109+
CustomChatChannelHeader(channelName: channel.name ?? "Unkown") {
92110
editShown = true
93111
}
94112
}
95113
.sheet(isPresented: $editShown) {
96114
Text("Edit View")
97115
}
98116
}
99-
100117
}
118+
101119
```
102120

103-
The next step we need to do is to create our own custom view factory (or update existing one if you've already created it) to return the newly created channel view modifier.
121+
The next step is to create a custom view factory (or update the existing one if it was already created) to return the newly created channel view modifier.
104122

105123
```swift
106124
class CustomFactory: ViewFactory {
@@ -118,7 +136,7 @@ class CustomFactory: ViewFactory {
118136
}
119137
```
120138

121-
Finally, we need to inject the `CustomFactory` in our view hierarchy.
139+
Finally, you need to inject the `CustomFactory` in your view hierarchy.
122140

123141
```swift
124142
var body: some Scene {
@@ -128,23 +146,43 @@ var body: some Scene {
128146
}
129147
```
130148

131-
These are all the steps needed to provide your own navigation header in the chat channel.
149+
These are all the steps needed to provide your own navigation header in the chat channel. Take a look at the comparison between the default implementation and the custom one.
150+
151+
![Depiction of the channel header with and without a custom channel header.](../../assets/channel-header-custom.png)
132152

133153
## Using the Chat Info Screen
134154

135-
In most chat apps, the navigation bar contains a link to a screen that contains information about the chat, such as its participants, list of the pinned messages, files, media, etc, as well as a possibility to add members to the chat. This view is displayed by default if you tap on the right navigation bar button in the channel header.
155+
In many chat apps, the navigation bar contains a link to a screen that contains information about the chat, such as its participants, list of the pinned messages, files, media, etc, as well as a possibility to add members to the chat. This view is displayed by default if you tap on the right navigation bar button in the channel header.
156+
157+
If you want to use this screen in your custom navigation bar (or anywhere else), you can simply initalize the `ChatChannelInfoView` with a channel.
136158

137-
If you want to use this screen in your custom navigation bar (or anywhere else), you can simply initalize it with a channel.
159+
In order for it to be integrated in the same context as above, your `CustomChatChannelHeader` would now look like this:
138160

139161
```swift
140-
ToolbarItem(placement: .navigationBarTrailing) {
141-
NavigationLink(destination: ChatChannelInfoView(channel: channel)) {
142-
ChannelAvatarView(
143-
avatar: headerImage,
144-
showOnlineIndicator: onlineIndicatorShown,
145-
size: CGSize(width: 36, height: 36)
146-
)
147-
.offset(x: 8)
162+
public struct CustomChatChannelHeader: ToolbarContent {
163+
164+
public var channelName: String
165+
// highlight-next-line
166+
public var channel: ChatChannel
167+
public var onTapTrailing: () -> ()
168+
169+
public var body: some ToolbarContent {
170+
ToolbarItem(placement: .principal) {
171+
Text(channelName)
172+
}
173+
174+
ToolbarItem(placement: .navigationBarTrailing) {
175+
// highlight-start
176+
NavigationLink(destination: ChatChannelInfoView(channel: channel)) {
177+
Image(systemName: "info.circle")
178+
.resizable()
179+
}
180+
// highlight-end
181+
}
148182
}
149183
}
150184
```
185+
186+
This will display the info button on the trailing edge of the header view and navigate to the detail screen once the user taps on it.
187+
188+
![Depiction of the navigation from the trailing icon in the channel header that leads to the info screen.](../../assets/channel-header-info-screen.png)

0 commit comments

Comments
 (0)