アプリに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)にスクロールします...
わかりました。私の調査と他の回答に基づくと、問題は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];
私が見つけた解決策はまったくエレガントではありませんが、機能します:
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];
今日気づいた。私の場合、問題は明らかにテキストビューがビューの最初のコントロールであることに関連しています。ドキュメントアウトラインの2番目の場所(たとえばUILabelの後)に移動すると、オフセットがなくなりました。
おそらくこれは、iOS7のナビゲーションバーの新しい動作のために意図的に行われています。
[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];
});
私は頼らなければならなかった
[displayText scrollRangeToVisible:NSMakeRange([displayText.text length], 0)];
しかし、それに関する大きな問題は、テキストの先頭から始まり、テキストに追加するたびに最後までスクロールすることです。 Mihaiのソリューションもそれを行います。