web-dev-qa-db-ja.com

iOS7のUITextViewcontentOffset

アプリにUITextViewがあります。新しい文字列が追加されるたびに、コンテンツオフセットを動的に変更する必要があります。以下のコードは、iOS 6以前のバージョンでは正常に機能しますが、iOS7では機能しません。

CGPoint offset = CGPointMake(0, self.textView.contentSize.height - self.textView.frame.size.height);
[self.textView setContentOffset:bottomOffset animated:YES]; 

なぜ何か考えがありますか?

あなたより。

[〜#〜] update [〜#〜]

UITextViewは、contentOffsetを適切に設定しないか、他の何かがそれを台無しにします。結果は期待どおりではありません(iOS 6以前のバージョンでの結果)。

新しいプロパティ「textContainerInset」も設定しようとしましたが、まだ結果がありません...

self.textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)    

[〜#〜] update [〜#〜]

DidScrollデリゲートメソッドでわかるように、コンテンツオフセットに正の値を渡すと、(0,0)にスクロールします。たとえば、コンテンツオフセットを(0,35)に設定すると、(0,0)にスクロールします...

16
Mihai Ghete

わかりました。私の調査と他の回答に基づくと、問題はUITextViewのコンテンツの高さであり、特定のオフセットへのスクロールではありませんでした。 iOS7で機能するはずの方法で機能するソリューションは次のとおりです。

まず、次のようにUITextViewを再作成する必要があります。

    NSString *reqSysVer = @"7.0";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    BOOL osVersionSupported = ([currSysVer compare:reqSysVer  options:NSNumericSearch] != NSOrderedAscending);

    if (osVersionSupported) {

        NSLog(@"reset chatoutput");

        CGRect outputFrame = self.chatOutput.frame;

        [chatOutput removeFromSuperview];
        [chatOutput release];
        chatOutput = nil;

        NSTextStorage* textStorage = [[NSTextStorage alloc] init];
        NSLayoutManager* layoutManager = [NSLayoutManager new];
        [textStorage addLayoutManager:layoutManager];
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
        [layoutManager addTextContainer:textContainer];
        chatOutput = [[UITextView alloc] initWithFrame: outputFrame
                                           textContainer: textContainer];
        // if using ARC, remove these 3 lines
        [textContainer release];
        [layoutManager release];
        [textStorage release];

        [self.view addSubview: chatOutput];
    }

次に、このメソッドを使用して、UITextViewコンテンツの高さを取得します。

- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
{
     UITextView *calculationView = [[UITextView alloc] init];
     [calculationView setAttributedText:text];
     CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];

     NSLog(@"size: %f", size.height) ;

     return size.height;
}

これで、コンテンツオフセットを設定できます。

CGPoint bottomOffset;

bottomOffset = CGPointMake(0, [self textViewHeightForAttributedText: self.chatOutput.attributedText andWidth: self.chatOutput.frame.size.width] - self.chatOutput.frame.size.height);

[self.chatOutput setContentOffset:bottomOffset animated:YES];

[〜#〜] update [〜#〜]

Apple NSAttributedStringのドキュメント: "NSAttributedStringオブジェクトのデフォルトフォントはHelvetica12ポイントであり、プラットフォームのデフォルトシステムフォントとは異なる場合があります。 。」

結論として、異なるサイズの異なるフォントを使用する場合は、それらもNSAttributeStringインスタンスに設定する必要があります。そうしないと、返される高さが期待に対応しません。次のようなものを使用することをお勧めします。

    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject: [UIFont systemFontOfSize: 18.0] //or any other font or size
                                                                forKey: NSFontAttributeName];
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: currentPost.postMessageText attributes: attrsDictionary];
    frame.size.height = [self textViewHeightForAttributedText: attributedString andWidth: 280.0];
    [attributedString release];
4
Mihai Ghete

私が見つけた解決策はまったくエレガントではありませんが、機能します:

UITextViewのcontentOffsetを(0,0)に設定してから、目的のオフセットに設定します。なぜこれが機能するのかわかりませんが、今のところ私が見つけた最良の解決策です。

CGPoint bottomOffset = CGPointMake(0, self.textView.contentSize.height - self.textView.frame.size.height);
[self.textView setContentOffset: CGPointMake(0,0) animated:NO]; 
[self.textView setContentOffset:bottomOffset animated:YES]; 
8
Mihai Ghete

今日気づいた。私の場合、問題は明らかにテキストビューがビューの最初のコントロールであることに関連しています。ドキュメントアウトラインの2番目の場所(たとえばUILabelの後)に移動すると、オフセットがなくなりました。

おそらくこれは、iOS7のナビゲーションバーの新しい動作のために意図的に行われています。

5
vidonism

@vidonismの answer は機能しますが、これはさらに優れています。

// in -viewDidLoad of UIViewController
self.automaticallyAdjustsScrollViewInsets = NO;

これに関する受け入れられた回答のトップコメントも参照してください 質問 。これは、ViewControllerのメインビューの最初のサブビューであるUIScrollViewの動作を説明している可能性があります。
これが予想される動作なのかバグなのか、はっきりとはわかりません。

2
race_carr

[textView setScrollEnabled:NO]があったので、以前の回答はどれもうまくいきませんでした。だから、私はこれで終わった:

[textView setScrollEnabled:YES]
[self.text setContentOffset:CGPointMake(0, page * self.text.frame.size.height) animated:NO];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.text setScrollEnabled:NO];
});
0
Artem

私は頼らなければならなかった

[displayText scrollRangeToVisible:NSMakeRange([displayText.text length], 0)];

しかし、それに関する大きな問題は、テキストの先頭から始まり、テキストに追加するたびに最後までスクロールすることです。 Mihaiのソリューションもそれを行います。

0
Nelson Ko