Reputation: 59
i wanted to migrate my simple chat app to explore swiftUI, Previously, I'm using collectionView for my chat view.
I uses one of messageKit's code to achieve reload data while keeping the offset of the cell
public func reloadDataAndKeepOffset() {
// stop scrolling
setContentOffset(contentOffset, animated: false)
// calculate the offset and reloadData
let beforeContentSize = contentSize
reloadData()
layoutIfNeeded()
let afterContentSize = contentSize
// reset the contentOffset after data is updated
let newOffset = CGPoint(
x: contentOffset.x + (afterContentSize.width - beforeContentSize.width),
y: contentOffset.y + (afterContentSize.height - beforeContentSize.height))
setContentOffset(newOffset, animated: false)
}
wanted to achieve similar result using swiftui. how do I achieve it?
I'm using scrollview and lazyVStack
here's an example of my current code
struct SimpleStruct {
let id: UUID
let num: Int
}
struct ChatViewV2: View {
@State var selectedAudio = ""
@State var many: [SimpleStruct] = (80...100).map { num in
.init(id: .init(), num: num)
}
@State var dataId: UUID?
var body: some View {
GeometryReader { geo in
ScrollViewReader { proxy in
ScrollView {
LazyVStack(alignment: .leading) {
AudioChatBubbleComponent(
selectedAudio: $selectedAudio,
maxWidth: geo.size.width)
ImageChatBubbleComponent(maxWidth: geo.size.width)
ForEach(Array(many.enumerated()), id: \.element.id) { (index, element) in
TextChatBubbleComponent(msg: "from \(element.num)")
.id(element.id)
.onAppear(perform: {
if index == 3 {
Task {
self.many = (80...100).map { num in
.init(id: .init(), num: num)
} + many
}
}
})
}
}
.scrollTargetLayout()
.padding()
}
}
.defaultScrollAnchor(.bottom)
}
.scrollPosition(id: $dataId)
}
}
currently, the scroll behavior is not what I expected, it didn't keep the scroll offset that solution was made by someone else and uses scrollPosition, didn't work out
Thank you
Upvotes: 0
Views: 155