class _TermsPolicyDetailScreenState extends State<TermsPolicyDetailScreen> {
late final WebViewController _webViewController;
bool _loading = true;
@override
void initState() {
super.initState();
_loading = true;
_webViewController = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// progress == 100이면 로딩 끝.
if(progress == 100) {
setState(() {
_loading = false;
});
}
},
onPageStarted: (String url) {},
onPageFinished: (String url) async {
Timer(const Duration(milliseconds: 500), () async {
if (Platform.isIOS) {
await _webViewController.runJavaScript('window.scrollTo(0, 0);');
}
});
},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if(request.url.contains('ourtube')) {
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
},
),
)
..loadRequest(Uri.parse(widget.termsPolicyType.url));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CommonWidget.appBar(context, title: widget.termsPolicyType.title),
backgroundColor: AppColor.wh,
body: Container(
padding: AppInset.all8,
child: _loading ? const Center(
child: CircularProgressIndicator(color: AppColor.blue300,),
) : WebViewWidget(
controller: _webViewController,
),
),
);
}
}
iOS의 경우, 웹뷰에서 로딩한 콘텐츠의 길이가 화면보다 길 때, 최초 스크롤의 위치가 맨 위가 아닌 중간에 가 있는 경우가 많다. 이 때문에 위의 자바스크립트 코드를 임의로 추가해서, iOS일 때만 실행되도록 했다.
관련 내용 : https://github.com/flutter/flutter/issues/47139#issuecomment-1311924105