WebView with UIScrollViewDelegate support.
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
var url: URL
var scrollViewDelegate: UIScrollViewDelegate?
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.scrollView.delegate = scrollViewDelegate
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}}
Observable ScrollViewDetector
import UIKit.UIScrollView
final class ScrollViewDetector: NSObject, ObservableObject, UIScrollViewDelegate {
@Published var isScrolledEnd = false
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let contentLoaded = scrollView.contentSize.height > 1000
let endOfContentReached = scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.size.height < 100
if contentLoaded && endOfContentReached {
isScrolledEnd = true
}
}}
Agreement view with sticky footer button.
import SwiftUI
struct AgreementView: View {
@StateObject var scrollViewDetector = ScrollViewDetector()
var body: some View {
GeometryReader { geometry in
ZStack {
WebView(url: URL(string: "YOUR URL")!, scrollViewDelegate: scrollViewDetector)
// Footer Navigation Link
NavigationLink {
EmptyView()
} label: {
// Your Label
Button("Accept")
.padding()
.background(Color.white.opacity(!scrollViewDetector.isScrolledEnd ? 0.9 : 0.0))
}
.position(x: geometry.width(0.5), y: geometry.height(0.9))
.opacity(!scrollViewDetector.isScrolledEnd ? 0.6 : 1.0)
.disabled(!scrollViewDetector.isScrolledEnd ? true : false)
}
}
}}