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
  • labelPoints to theMessageViewThat’s page A.
  • destinationPoint to the page B to jump to.
  • isActiveIs aBoolValue, throughisActive=trueimplementationjumpAnd vice versaisActive=falseimplementationreturnThe effect. Here by@StateAnnotations to modifyMessageChatPresentedVariable to make it fromValue passedprogrammingreferenceThis 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 modifyMessageChatPresentedVariable to convert toBindingThis is used to inform the child component that this variable isreference, so the child component also needs to receive@BindingAnnotation 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: combinationp.addCurveCan.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)