SwiftUI로 채팅 리스트 화면 만들기

 
 
Introduction

 
이번 포스팅이 첫 페이지 라면, 이전 포스팅(Xcode에서 SwiftUI시작하기)을 확인 해주시기 바랍니다. 그리고 순차적으로 따라와서 해보시길 권합니다. 
 
이번 포스팅에서 다뤄지는 내용은 바로 이전 포스팅 “친구목록 화면 만들기” 와 인터페이스가 동일합니다. 그래서 만들기가 조금 더 간편할 것 같죠? ^^ 하지만 몇가지 숨겨진 함정이 있긴하지만, 그래도 화면 인터페이스부터 먼저 만들도록 하겠습니다. 
 
 
#무엇이 필요할까?
  • Text
    • system Icon
  • Image
  • ScrollView
  • NavigationView
  • VStack, HStack
  • 아이콘(?)
 

 

 

 
Apple SF simbols app for macOS를 이용한 시스템 아이콘 이용하기

 
먼저 본 포스팅에서 사용하기 위한 [종소리][핀][채팅] 아이콘을 사용하기위해, 먼저 포스팅 해두었던 SF simpbols app for macOS를 살펴보고 설치를 해주시기 바랍니다. 물론, 본 포스팅에서는 필요에 따른 부분은 작성되어있기때문에 추가 설치하지 않고 진행하셔도 됩니다. 그 외는 둘러보시고 필요한 아이콘의 이름을 따라 작성해주시면 됩니다. 
 
 
채팅 로그 Sample Data 추가

 
이번에도 친구목록 샘플 데이터와 유사하게 작성을 해보도록 하겠습니다. 이를 위해 ChattingLog.swift 를 생성하도록 합니다. 
코드를 하나씩 추가하면서 살펴보도록 할까요? 
 
(주의: 이전 포스팅에 이어, 동일한 프로젝트에서 수행하시기 바랍니다. )
 
ChattingLog.swift
struct ChattLog: Codable, Identifiable {
    let id: UUID = UUID()
    let FriendName:String
    let LastMsg:String
    var headCount:Int
    var IconName:BtnIcon
}
 
이것저것 화면 UI와는 상관 없는 부분들이 있지만, 향후 작업을 위해 그대로 사용하겠습니다.
채팅 리스트에는 마지막으로 대화한 친구들의 리스트가 있으며, 마지막 대화가 보입니다. 그리고 각각의 채팅 방에 대한 핀설정,무음설정, 등이 있습니다. 이렇게 시스템 아이콘은 따로 BtnIcon으로 추출하여 사용하도록 하겠습니다. 
struct BtnIcon: Codable {
    
    var msg:String
    var isNotification:Bool
    var isPin:Bool
    var isChat:Bool
    
    init( _ msg:String="None”, _ notification:Bool, _ pin:Bool, _ Chat:Bool )
    {
        self.msg = msg
        self.isNotification = notification
        self.isPin = pin
        self.isChat = Chat
    }
}
 
각 채팅방의 설정으로 notification, pin를 설정할 수 있습니다. (본문의 3번째 아이콘은 없이 하셔도 됩니다^^)
이에 따라 상위 코드와 같이 코드를 작성합니다. 
 
 
채팅 리스트 화면 만들기

 
이어서 채팅 리스트 화면을 만들도록 하겠습니다. 코드를 보면 아시겠지만, 친구목록 화면과 코드가 동일합니다.  추가되는 부분은 시스템 아이콘 추가하는 부분이겠죠? 
 
body
struct ContentView: View {
    var body: some View {
        List {
            ForEach(ChattLogSamples) {
                ChatLogView($0.FriendName, $0.LastMsg, $0.headCount, $0.IconName)
            }
        }
    }
}
body부분은 수행하는 구조체만 다를 뿐 형태는 동일하죠? 입력 파라미터는 천천히 알아보도록 하겠습니다. 
struct ChatLogView: View {
    let widthText:CGFloat = 300
    let ImageWH:CGFloat = 40
    
    var ImgName:String
    var FriendName:String
    var LastMsg:String
    var headCount:Int
    var IconName:BtnIcon
}
 
구조체의 변수들은 친구목록 구조체와 동일하죠?  headCount, BtnIcon이 추가가 되었네요!?
struct ChatLogView: View {
   
    init( _ name:String,
          _ msg:String = "noMsg",
          _ count:Int = 2,
          _ btnState:BtnIcon = BtnIcon("none", true, true, true))
    {
        self.FriendName = name
        self.LastMsg = msg
        self.headCount = count
        self.IconName = btnState
        self.ImgName = "none"
        setImgName(UserName: self.FriendName)
        
        print("Image Name: \(ImgName)")
    }
}
생성자도 크게 다르지 않습니다.  추가된 변수들에 대한 값을 초기화 해주시면 됩니다. 
struct ChatLogView: View {
    var body: some View {
        HStack {
            Image(self.ImgName) // "01"
                .resizable()
                .frame(width: ImageWH, height: ImageWH)
                .clipShape(Circle())
            
            VStack {
                NotificationOption
                    .frame(width: widthText, height: 20, alignment: .leading)
                
                lastMsg
                    .frame(width: widthText, height: 20, alignment: .leading)
            }
            .frame(width: 300, height: 40)
        }
    }
}
마지막 body를 확인해보시면 전체적인 틀은 동일하죠?  추가된 부분은 NotificationOption, lastMsg 입니다. 이부분은 extension을 이용하여 코드를 추가하였습니다. 하나씩 살펴보도록 할까요? 
private extension ChatLogView {
    
    var NotificationOption: some View {
        HStack {
            Text(FriendName)
                .font(.headline)
            
            Text(getCount(count: headCount))
                .font(.footnote)
            
            if IconName.isNotification {
                Image(systemName: "bell")
            } else {
                Image(systemName: "bell.slash")
            }
            
            if IconName.isPin {
                Image(systemName: "pin")
            } else {
                Image(systemName: "pin.fill")
            }
            
            if IconName.isChat {
                Image(systemName: "message")
            } else {
                Image(systemName: "message.fill")
            }
        }
    }
    
    var lastMsg: some View {
        HStack {
            Text(LastMsg)
                .font(.footnote)
        }
    }

    mutating func setImgName( UserName:String ) {
        for friend in FriendSamples {
            if friend.UserName == UserName {
                self.ImgName = friend.ImgName
                break
            }
        }
    }
    
    func getCount( count:Int) -> String {
        let CountString = String(count)
        return CountString
    }
}
NotificationOption은 친구목록UI에 아이콘들이 추가로 들어가 있습니다. 앞서 설명한 아이콘을 사용하기 위해서는 다음과 같이 사용 하시면 됩니다. 
Image(systemName: "bell”)
Image(systemName: "bell.slash")
 
그 외 크게 설명할 부분은 없어보이지만, 향후 실시간 데이터를 이용할 때에 문제가 커지니 어떻게 수정할지 알아둬야 하겠죠? 

 

 

 

 
코드 작성이 완료되면 다음과 같이 화면을 볼 수 있습니다. 
 
 
친구목록과 채팅 리스트 인터페이스가 크게 다르지 않기 때문에 쉽게 만들 수 있겠죠? 
 
향후 포스팅 예고

 
다음 포스팅은 채팅UI입니다. 채팅 UI는 친구목록혹은 채팅리스트에서 선택하였을 경우 보이는 화면인데, 미리 화면 구성을 하고나서 이후에 TabView 및 NavigationBar를 이용하여 전환하는 방법을 알아보도록 하겠습니다. 궁금하죠~? 
 
 
 
 

 

 

이 글을 공유하기

댓글(0)

Designed by JB FACTORY