16

作業中の iPhone アプリケーション用にリッチテキスト エディター (HTML エクスポート機能付き) を試していますが、iOS 5 の WebKit サポートをcontentEditable/に使用することにしましdesignModeた。私は、必要なものを壊している1つの問題で壁にぶつかりました。UIWebView でコンテンツを編集する場合、たとえば UITextView のように、カーソルに追従する自動スクロールはありません。入力中、カーソルは scrollView の下に留まり、ユーザーは手動で上にスクロールする必要があります。

関連するコードを次に示します。

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *string = @"document.body.contentEditable=true;document.designMode='on';void(0)";
    [webView stringByEvaluatingJavaScriptFromString:string];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}

この問題を解決する方法はありますか? これが Safari でも発生するのか、UIWebViewWebKit の実装でのみ発生するのかはわかりません。

この問題が発生した場合は、必ずhttps://bugreport.apple.comにアクセスしてrdar://16455638を複製してください。

4

5 に答える 5

11

何時間もの調査の結果、より良い解決策を見つけたので、共有したいと思いました。

iOS 5のcontentEditable実装には、メインのscrollViewがカレットでスクロールしないというバグがあります。bodyタグ(または動的にサイズ設定された要素)をcontentEditableにすると、カレットは常に画面から消えます。

編集可能なdivをoverflow:scrollに設定すると、divがスクロールすることに気付くでしょう。divのスクロールは、デフォルトでは「バウンス」またはスクロールバーを備えていませんが、-webkit-overflow-scrolling: touch属性をdivに適用してこれを修正できます。

この情報を使用して、次のようなラッパーで修正できます。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"/>
<style type="text/css">
    html, body {height: 100%;}
    body {
        margin: 0;
    }
    #wrap {
        height: 100%;
        width: 100%;
        overflow-y: scroll;
        -webkit-overflow-scrolling: touch;
    }
    #editor {
        padding: 10px;
    }
</style>
</head>
<body>
<div id="wrap">
    <div id="editor" contenteditable="true">

    </div>
</div>
</body>
</html>

基本的に、ドキュメントの代わりにdivをスクロールしています。

残念ながら、divの「scrollView」は仮想キーボードを認識しないため、カレットはキーボードの後ろに表示されなくなります。ただし、キーボードの後ろの下部にある画面上で、キャレットの位置がまだ表示されていることに気付くでしょう。したがって、これを修正するには、キーボードに対応するようにdiv/UIWebViewの高さを低くします。

他にやりたいことは、メインのscrollViewでスクロールを無効にすることです。

webView.scrollView.scrollEnabled = NO;

メインのscrollViewはとにかくスクロールしないはずですが、スクロールの不具合を防ぐ必要があります。

于 2012-07-26T18:03:37.467 に答える
4

私自身の質問に答えるために、最終的には、これが複数の iOS バージョンで正しく動作するように多くの作業を行うことになりました。すべてのスクロール イベントは、 がUIWebViewその を管理しようとしたことが原因であることがわかりましたUIWebScrollView。を使用する代わりにUIWebView、内部のUIWebDocumentView/UIWebBrowserViewを取得して独自のスクロール ビューに追加することにしました。これにより、コンテンツのサイズとスクロールを自分で管理し、以前に経験した問題のほとんどを取り除くことができました.

于 2014-01-01T18:53:52.770 に答える
1

まず、キーボード通知を登録する必要があり、その keyboardWillShow メソッドで、0.1 タイマー間隔でスクロール メソッドをトリガーします。

 -(void) keyboardWillShow:(NSNotification *)note
    {

        timer   =   [NSTimer    scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(scroll) userInfo:nil repeats:YES];

    }

    -(void) keyboardWillHide:(NSNotification *)note
    {
        [timer invalidate];

    }

.h ファイルで 1 つのメンバ変数を作成し、init() メソッドでメモリを割り当てます。

  NSString    *prevStr;

そのスクロール メソッド内で、次の操作を行います。

-(void)scroll{

    if (![prevStr isEqualToString:[WebView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"]]) {
        prevStr  =   [[WebView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"] retain];
        NSInteger height = [[WebView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] intValue];
        NSString* javascript = [NSString stringWithFormat:@"window.scrollBy(0, %d);", height];   
        [WebView stringByEvaluatingJavaScriptFromString:javascript];   
    }

}

これにより、コンテンツを編集していて、コンテンツが WebView フレームよりも大きい場合に、一番下までスクロールできます。それ以外の場合は、ページの上部までスクロールできます (その時点で自動スクロールが保持されます)。

于 2011-12-22T14:19:12.413 に答える