above
# SwiftUI Actual Combat – copy write wechat App (I) | August more text challenge
A, goals,
In this section we will implement the chat window page.
Second, the train of thought
-
The navigation area. By clicking the button < Back to List page in the upper left corner of the navigation area. Similarly, clicking on a list element in a list page can jump to the corresponding window page.
-
Content area. Chat bubble + user icon, output through loop.
-
Toolbar, 4 ICONS + input box.
3. The NavigationLink page is displayed
Let’s go back to the MessageView we talked about in the last section. SwiftUI jumps from page A to page B using the NagivationLink component.
NavigationLink(
destination: Text("Destination"),
isActive: $MessageChatPresented,
label: {
MessageView(imageName: message.imageName, publisher: message.publisher, date: message.date, message: message.message)
})
Copy the code
label
Points to theMessageView
That’s page A.destination
Point to the page B to jump to.isActive
Is aBool
Value, throughisActive=true
implementationjump
And vice versaisActive=false
implementationreturn
The effect. Here by@State
Annotations to modifyMessageChatPresented
Variable to make it fromValue passed
programmingreference
This can then be passed between the parent component and the child component. When the child component changes its value, the parent component changes as well.$
Symbols to modifyMessageChatPresented
Variable to convert toBinding
This is used to inform the child component that this variable isreference
, so the child component also needs to receive@Binding
Annotation embellishment. This usage isTwo-way binding
.
The results are as follows:
NavigationLink assigns a return button < to the destination by default. To customize the return button, change the value of the isActive MessageChatPresented variable to false.
Similarly, create a separate messagechatView.swift file to write the chat window. Then modify destination: MessageChatView().
In the navigation window, there is a title and a button in the upper right corner.
As in the previous section, use NagivationTitle and navigationBarItems.
The code is as follows:
Text("Hello, World!")
.navigationTitle(title)
.navigationBarItems(trailing: Image(systemName: "person"))
Copy the code
4. Path chat bubble
Now you need to draw the topic of the chat content, the chat bubble. There is a small triangle on the left and right of the bubble, which is an irregular Shape. Therefore, the existing Shape component cannot meet the conditions, so we need to draw it by ourselves.
SwiftUI provides Shape protocol, implement the protocol and complete the PATH method to draw custom graphics.
struct ChatBubbleShape: Shape {
func path(in rect: CGRect) -> Path {
let width = rect.width
let height = rect.height
let path = Path{p in
p.move(to: CGPoint(x: 0, y: 0)) // move to the axis 0,0, which defaults to the upper-left corner
p.addLine(to: CGPoint(x: width, y: 0)) // Move the width distance to the right
p.addLine(to: CGPoint(x: width, y: height/3)) // Move down to height/3
p.addLine(to: CGPoint(x: width+20, y: height/2)) // Move 20 to the right and down to height/2
p.addLine(to: CGPoint(x: width, y: 2*height/3)) // Move 20 to the left and down to 2*height/3
p.addLine(to: CGPoint(x: width, y: height)) // Move down to height
p.addLine(to: CGPoint(x: 0, y: height)) // Move to the left to x=0
p.addLine(to: CGPoint(x: 0, y: 0)) // Move up to x=0,y=0
}
return path
}
}
Copy the code
The drawing sequence is shown in the figure below:
The final effect is as follows:
The final work is also very simple and repetitive, here is not a list, just to illustrate the implementation.
- Chat bubbles are divided into two kinds: refer to the drawing ideas above.
- Bubble width: Can be dynamically adjusted according to the character length.
- Rounded corner problem: combination
p.addCurve
Can.The reference sample
Finally, ScrollView can be used to achieve the scrolling view, through the message content traversal to achieve the effect.
V. Toolbar andTextField
The toolbar menu consists of four buttons and a text field.
HStack{
Image(systemName: "text.bubble").font(.title)
Image(systemName: "waveform.circle").font(.title)
TextField("Input", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())
Image(systemName: "face.smiling").font(.title)
Image(systemName: "plus.circle").font(.title)
}.padding()
Copy the code
TextField has at least two arguments, the first of which is placeholder. The second parameter is the value of the input box, which needs to be bi-directional binding between the parent and child using @state and $decorates, so that once the user enters any value through the keyboard, the child component TextField senses it and changes the value to make the parent aware.
Finally, make the toolbar opaque by adding a Rectangle to the ZStack.
ZStack(alignment: .bottomLeading){
Rectangle().fill().foregroundColor(.white)
HStack{
Image(systemName: "text.bubble").font(.title)
Image(systemName: "waveform.circle").font(.title)
TextField("", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())
Image(systemName: "face.smiling").font(.title)
Image(systemName: "plus.circle").font(.title)
}.padding()
}.frame(height: 50)
Copy the code
Final result:
Attached: Code address
Gitee.com/dkwingcn/we…
Related articles
SwiftUI Actual Combat – Copy wechat App (3)
SwiftUI Actual Combat – Copy wechat App (4)