これを実装する class を frameLoadDelegate にしておく。
//_savedPosition は CGPoint;
//現在のスクロール位置を記憶するメソッド
- (void)rememberScrollPosition {
WebView* webView = self.webView;
NSScrollView* sv = [[[[webView mainFrame]frameView]documentView]enclosingScrollView];
if (sv) {
NSRect currentRect = [sv documentVisibleRect];
//前回の読み込みが完了していないときの対策で y==0 なら記録しない
//読み込み中じゃなくても y==0 なら何もしなくてよいのでスルー
if (currentRect.origin.y > 0) {
_savedPosition=currentRect.origin;
}
//isFlipped が NO なら計算必要? おそらく常に YES なので origin そのまま保存
}else{
_savedPosition = NSZeroPoint;
}
}
//frameLoadDelegate にしておくと呼ばれるメソッド
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
WebView* webView = self.webView;
CGFloat savedY = _savedPosition.y;
if (frame == [webView mainFrame] && savedY > 0) {
NSPoint pt = NSMakePoint(0, savedY);
[[[[webView mainFrame]frameView]documentView]scrollPoint:pt];
_savedPosition = NSZeroPoint;
}
//origin.x はとりあえず無視した
}
データ更新する前に上記 rememberScrollPosition を呼べばいいと思います。
- (void)updateContents:(NSString *)string {
//記憶
[self rememberScrollPosition];
//更新実行
[self.webView loadHTMLString:string baseURL:nil];
//ここで復元してもタイミングが早いので意味がない
}