これにはjavascriptを使用しています。コードをもう少し整理するためにクラスを使用しています (そのためthis
、コードにいくつか表示されます) が、これは必須ではありません。
// this is used to get the current coordinates of the selection - not very efficient, so it shouldn't be called too often
this.updateOffset = function() {
try{
var sel = window.getSelection();
range = sel.getRangeAt(0);
if(this.tmpSpan==null){
this.tmpSpan = document.createElement('span');
}
range.insertNode(this.tmpSpan);
this.yOffset = this.tmpSpan.offsetTop;
this.xOffset = this.tmpSpan.offsetLeft;
this.tmpSpan.parentNode.removeChild(this.tmpSpan);
}
catch(exc){
log('updateOffset:' + exc.toString());
}
}
// eContent is the div with 'contenteditable', while visibleHeight is an int, set from objective-c (depending on where the webview is positioned, keyboard height and screen height)
this.scrollToVisible = function(){
try {
if(this.eContent.clientHeight>this.visibleHeight){
this.updateOffset();
if(this.yOffset<window.pageYOffset){
window.scrollTo(0, this.yOffset);
}
else if(this.yOffset-window.pageYOffset>this.visibleHeight){
window.scrollTo(0, this.yOffset-this.visibleHeight);
}
}
}
catch (exc){
log('scrollToVisible: ', exc.toString());
}
}
Objective-C では、キーボードの表示中に visibleHeight を設定し、その後scrollToVisible
、キーボードの表示が終了したら呼び出します。
-(void)setVisibleHeight:(int)height{
[self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"docState.visibleHeight=%d", height]];
}
-(void)scrollToVisible{
[self stringByEvaluatingJavaScriptFromString:@"docState.scrollToVisible()"];
}
scrollToVisible
は、JavaScript イベント (onkeyup、onpaset、oncut) でも呼び出されます。これにより、「return」を押すか、複数の行を折り返す際の問題が修正されます。
この方法を選択した場合は、JavaScript をスクロールするときに十分に注意する必要があります。そうしないと、UIWebview コントロールで問題が発生する可能性があります (例: カーソルを間違った位置に配置する、カーソルを自動的に上に移動する)。文書など)
編集
に関するいくつかの説明visibleHeight
。私が覚えている限りでは、javascript から実際に見える高さを取得できなかったため、これを使用しました (document.body.clientHeight
キーボードの後ろの領域も含まれます)。
フルスクリーンで表示しているのでUIWebView
、表示される高さを次のように設定しています。
- (void)keyboardWillShow:(NSNotification *)notification {
...
NSDictionary *userInfo = [notification userInfo];
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
CGRect kbRect = [self.window convertRect:keyboardRect fromView:nil];
_kbRect = kbRect;
CGPoint sorigin = [self.superview convertPoint:self.frame.origin toView:nil];
int visibleHeight = _kbRect.origin.y-sorigin.y-_tlbInputAccessory.frame.size.height-lkPadBottom; // _tlbInputAccessory is a custom accessory view
[self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"docState.setVisibleHeight(%d)", height]];
...
}
これは のサブクラスから呼び出しているUIWebView
ため、コントロールself
を表すことに注意してください。UIWebView