2013-06-10 11 views
7

Chcę wyrównać tekst w pionie w środku w UItextView.UITextView alligining text vertical center

Używam następujący kod

UITextView *tv = object; 
    CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0; 
    topCorrect = (topCorrect < 0.0 ? 0.0 : topCorrect); 
    tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect} 

;

Jakoś to nie działa w systemie iOS 5, ponieważ zwrócona zawartość contentSize jest inna niż w systemie iOS6.

Dowolny pomysł, dlaczego contentSize tego samego tekstu jest inny w iOS 5 i iOS 6?

Odpowiedz

20

Dodaj obserwatora dla kluczowej wartości contentSize z UITextView gdy widok załadowany: -

- (void) viewDidLoad { 
    [textField addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL]; 
    [super viewDidLoad]; 
} 

dostosować contentOffset za każdym razem zmiany wartości contentSize: -

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
UITextView *tv = object; 
CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0; 
topCorrect = (topCorrect < 0.0 ? 0.0 : topCorrect); 
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect}; 
} 

nadzieję, że to pomaga ...

Możesz pobrać przewodnik od

https://github.com/HansPinckaers/GrowingTextView

+1

To nie powoduje, że tekst jest stale wycentrowany w pionie, ponieważ jeśli rozmiar UITextView jest zmieniany na przykład, gdy pojawi się klawiatura), wówczas zawartość UITextView powraca do górnego wyrównania. – motionpotion

+1

To jest świetny kawałek kodu oprócz jego wartości jako obserwatora klawiatury. Dzięki. –

+0

Miałem awarię podczas używania tego kodu w 'UITableView'. Działa dobrze na ios8, ale także musi usunąć obserwatora po wyrównaniu. Dodaj tę linię jako ostatnią linię metody "observeValueForKeyPath": [tv removeObserver: self forKeyPath: @ "contentSize"]; ' –

5

spróbować tego na metodzie observeValueForKeyPath na iOS7:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    { 
UITextView *tv = object; 

CGFloat height = [tv bounds].size.height; 
CGFloat contentheight; 

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) { 
    contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height; 
    NSLog(@"iOS7; %f %f", height, contentheight); 
}else{ 
    contentheight = [tv contentSize].height; 
    NSLog(@"iOS6; %f %f", height, contentheight); 
} 

CGFloat topCorrect = height - contentheight; 
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect); 
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect}; 
} 

zostać określone: ​​

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 
0

I zostały zmodyfikowane rozwiązanie Arpit tak, to może pasować rozszerza TextView contentView

static NSString *const kContentOffsetKeyPath = @"contentOffset"; 

-(void)viewDidLoad { 
    [self.replyTextView addObserver:self 
         forKeyPath:kContentOffsetKeyPath 
          options:(NSKeyValueObservingOptionNew) 
          context:NULL]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if ([keyPath isEqualToString:kContentOffsetKeyPath]) { 
     // To keep scrolling to bottom while typing and text content view is larger than maximum limit 
     if (textView.contentSize.height > singleLineHeight) { 
      UITextView *textView = object; 
      CGFloat topCorrect = ([textView bounds].size.height - [textView contentSize].height * [textView zoomScale])/2.0; 
      CGFloat fineTune = -3.0; 
      topCorrect = (topCorrect < fineTune ? fineTune : topCorrect); 
      // To avoid recursion 
      [textView removeObserver:self forKeyPath:kContentOffsetKeyPath]; 
      textView.contentOffset = (CGPoint){.x = 0, .y = -topCorrect}; 
      // add observer back 
      [textView addObserver:self 
         forKeyPath:kContentOffsetKeyPath 
          options:(NSKeyValueObservingOptionNew) 
          context:NULL]; 
     } 
    } 
} 

- (void)dealloc { 
    [self.replyTextView removeObserver:self forKeyPath:kContentOffsetKeyPath]; 
    }