Im using UIScrollView inside UIViewRepresentable and Im loading the items from database by chunks where each chunk contains 15 items.
When I perform loading operation where each chunk is loaded when user scrolls to top of the scrollview, everything works fine, until I load around 3-5 chunks (which means user scrolled to the top 3-5 times). When this amount or more is loaded, white thick bar appears on the top of the scroll view which behaves as if I added a white rectangle to the top.
If I load the data all at once, instead of loading by chunks, the scroll view is behaving alright.
Im using this scroll view:
// EXTENDED SCROLL VIEW
//--------------------------------------------------
struct ExtendedScrollView<Content: View>: UIViewRepresentable {
//--------------------------------------------------
// VARIABLES
//--------------------------------------------------
var content: () -> Content
var ScrolledToTop: () -> Void
@Binding var messageAreaY: CGFloat
@Binding var messageAreaIsFocused: Bool
//--------------------------------------------------
// METHODS
//--------------------------------------------------
// MAKE UIVIEW
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator
scrollView.isScrollEnabled = true
scrollView.showsVerticalScrollIndicator = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.bounces = true
return scrollView
}
//--------------------------------------------------
// UPDATE UIVIEW
func updateUIView(_ uiView: UIScrollView, context: Context) {
for subview in uiView.subviews {
subview.removeFromSuperview()
}
let hostView = UIHostingController(rootView: content())
hostView.view.translatesAutoresizingMaskIntoConstraints = false
uiView.addSubview(hostView.view)
NSLayoutConstraint.activate([
hostView.view.topAnchor.constraint(equalTo: uiView.topAnchor),
hostView.view.bottomAnchor.constraint(equalTo: uiView.bottomAnchor),
hostView.view.leadingAnchor.constraint(equalTo: uiView.leadingAnchor),
hostView.view.trailingAnchor.constraint(equalTo: uiView.trailingAnchor)
])
}
//--------------------------------------------------
// MAKE COORDINATOR
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
//--------------------------------------------------
// COORDINATOR
//--------------------------------------------------
class Coordinator: NSObject, UIScrollViewDelegate, UIGestureRecognizerDelegate {
var parent: ExtendedScrollView
var startSwipePos: CGFloat = 0
var currentSwipePos: CGFloat = 0
//--------------------------------------------------
// CONSTRUCTOR
init(_ parent: ExtendedScrollView) {
self.parent = parent
}
//--------------------------------------------------
// SCROLL VIEW DID SCROLL
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
let scrollViewHeight = scrollView.frame.size.height
// IF USER REACHED BOTTOM
if offsetY + scrollViewHeight >= contentHeight {
parent.ScrolledToTop()
}
// HANDLE DRAG GESTURE
if scrollView.panGestureRecognizer.state == .began { // if gesture began
startSwipePos = scrollView.panGestureRecognizer.location(in: UIApplication.shared.windows.first).y // set start position
}
if scrollView.panGestureRecognizer.state == .changed { // if gesture proceeds
currentSwipePos = scrollView.panGestureRecognizer.location(in: UIApplication.shared.windows.first).y // update current position
if currentSwipePos > parent.messageAreaY && startSwipePos < parent.messageAreaY && parent.messageAreaIsFocused {
DispatchQueue.main.async {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
}
}
}
}