UIHostingConfiguration | Apple Developer Documentation
A content configuration suitable for hosting a hierarchy of SwiftUI views.
developer.apple.com
장점
- 빠른 뷰 코드 작성 가능
- UIKit에서 작성한 코드 스타일에 크게 위반하지 않고 ListCell만 SwiftUI의 View를 도입해서 빠른 구현 가능

구현 요소
- ChatAsset ⇒ SwiftUI의 View에서 사용할 수 있는 형태의 데이터 모델
- DataSource ⇒ UICollectionView에서 사용하는 DiffableDatasource 적용함
- ChatCell ⇒ SwiftUI의 View
UICollectionView에 ChatCell Registration 프로퍼티 제작
extension DMChatViewController: UICollectionViewDelegate, UICollectionViewDataSourcePrefetching{
var chatCellRegistration: UICollectionView.CellRegistration<UICollectionViewListCell,ChatItem.ID>{
UICollectionView.CellRegistration {[weak self] cell, indexPath, itemIdentifier in
guard let self else{ fatalError("메모리 SELF 오류!!") }
guard let item = dataSource.chatModel.fetchByID(itemIdentifier) else {return}
cell.backgroundColor = .clear
cell.selectedBackgroundView = .none
if let itemAssets = dataSource.chatAssetModel.object(forKey: "\(item.chatID)" as NSString){
cell.contentConfiguration = UIHostingConfiguration(content: {
ChatCell(chatItem: item,images: itemAssets, profileAction: self.profileAction(userID:), imageAction: self.imageAction)
}).background(.white)
}else{
let itemAsset = self.dataSource.appendChatAssetModel(item: item)
cell.contentConfiguration = UIHostingConfiguration(content: {
ChatCell(chatItem: item,images: itemAsset, profileAction: self.profileAction(userID:), imageAction: self.imageAction)
}).background(.white)
}
}
}
}
셀 이벤트 처리
- 뷰 컨트롤러의 메서드로 뷰의 이벤트 처리를 위한 클로저를 삽입한다.
✅ 셀 선언 부 부분 - UIViewController
...
cell.contentConfiguration = UIHostingConfiguration(content: {
ChatCell(chatItem: item,images: itemAssets,
profileAction: self.profileAction(userID:),
imageAction: self.imageAction)
}).background(.white)
✅ 셀 뷰 init 및 저장 프로퍼티 부분 - SwiftUI View
struct ChatCell:View{
...
@ObservedObject var chatItem: CHChatView.ChatItem
@ObservedObject var images: CHChatView.ChatAssets
@DefaultsState(\.userID) var userID
@State private var date:String = "08:16 오전"
@State private var dateWidth:CGFloat = 0
let profileAction: ((Int)->Void) // 이벤트 클로져
let imageAction:(([String])->Void) // 이벤트 클로져
init(chatItem: CHChatView.ChatItem, images: CHChatView.ChatAssets,
profileAction: @escaping (Int) -> Void,imageAction:@escaping ([String]) -> Void) {
self.chatItem = chatItem
self.images = images
self.profileAction = profileAction
self.imageAction = imageAction
}
...
}
✅ 뷰 이벤트 처리 부분 - 채팅에 포함된 이미지를 출력하는 뷰 컴포넌트 이벤트
extension ChatCell{
var otherContents: some View{
...
ContainerImage(realImage: $images.images)
.drawingGroup()
.clipShape(RoundedRectangle(cornerRadius: 8))
.onTapGesture { // 이벤트 발생시 클로져 호출
imageAction(chatItem.images.map{$0.docFileToWebFile()})
}
}
}
셀 뷰에서 사용하는 데이터 모델 처리 (ChatAsset)
- 모델 데이터는 ObservableObject을 준수해 SwiftUI 하위 뷰에서 새로운 데이터 할당 시, 변화를 감지 할 필요가 있다. ⇒ 모델을 Class로 작성해야한다.
- StateObject가 아닌 ObservedObject 사용. 데이터 변경 시, 즉시 하위 뷰가 Rerendering될 필요가 있기 때문이다.
- UICollectionView의 셀에서 가져오는 데이터도 같이 수행하기 때문에,
Hashable프로토콜을 준수해야한다.
✅ 셀 뷰에서 사용하는 데이터
class MessageCellItem:ObservableObject,Hashable,Identifiable{
static func == (lhs: MessageCellItem, rhs: MessageCellItem) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) { hasher.combine(id) }
var id : Int{ messageID }
@Published var messageID: Int = 0
@Published var content:String? = nil
@Published var images:[String] = []
@Published var createdAt:String
@Published var profileID:Int = 0
@Published var profileName:String = ""
@Published var profileImage:String? = nil
init(id: Int, content: String? = nil, images: [String], createdAt: String, profileID: Int, profileName: String, profileImage: String? = nil) {
self.messageID = id
self.content = content
self.images = images
self.createdAt = createdAt
self.profileID = profileID
self.profileName = profileName
self.profileImage = profileImage
}
}'이모저모 > UIKit' 카테고리의 다른 글
| UIImage 메모리 최적화 (0) | 2023.12.11 |
|---|---|
| 커스텀 이미지 피커 뷰 만들기 #2 (0) | 2023.12.02 |
| 커스텀 이미지 피커 뷰 만들기 #1 (0) | 2023.12.02 |
| 싱글톤 앨범 이미지 서비스 만들기 with Rx or Combine (0) | 2023.11.28 |
| UIButton State 애니메이션용 모듈 만들고 적용하기 (0) | 2023.11.25 |
댓글