2013-10-01 24 views
15

Ho un UITextView nella mia app. Devo cambiare il contenuto in modo dinamico in modo dinamico ogni volta che viene aggiunta una nuova stringa. Il soffietto codice funziona bene su iOS 6 e versioni precedenti, ma non su iOS 7.UITextView contentOffset su iOS 7

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

Avete delle idee perché?

Grazie.

UPDATE

L'UITextView non imposta la sua contentOffset come dovrebbe, o qualcosa d'altro rovinare tutto. Il risultato non è come previsto (come è su iOS 6 o versioni precedenti).

Ho anche provato a installare la nuova proprietà "textContainerInset", ma ancora nessun risultato ...

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

UPDATE

Come posso vedere nel metodo delegato didScroll, quando passo un valore positivo per l'offset del contenuto, scorre a (0,0). Per esempio, ho impostato il contenuto offset (0,35) e scorre a (0,0) ...

+0

Ho aggiornato il mio post. –

risposta

4

Ok, in base alle mie ricerche e altre risposte, il problema era l'altezza del contenuto dello UITextView e non lo scorrimento verso uno specifico offset. Ecco una soluzione che funziona il modo in cui dovrebbe funzionare per iOS 7:

In primo luogo, è necessario ricreare il UITextView in questo modo:

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]; 
    } 

Quindi, utilizzare questo metodo per ottenere l'altezza UITextView contenuti:

- (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; 
} 

Ora è possibile impostare il contenuto di offset:

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

ho letto questo nella documentazione Apple per NSAttributedString: "Il carattere predefinito per gli oggetti NSAttributedString è Helvetica 12 punti, che può essere diverso dal carattere di sistema predefinito per la piattaforma"

In conclusione, se si utilizzano caratteri diversi di dimensioni diverse, è necessario impostarli anche sull'istanza NSAttributeString.In caso contrario, l'altezza restituita non corrisponderà alle tue aspettative. Si consiglia di utilizzare qualcosa di simile:

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]; 
+0

Funziona come un incantesimo. Buon lavoro :) –

6

La soluzione che ho trovato non è elegante a tutti, ma funziona:

Ho impostato il contentOffset di UITextView su (0,0) prima di impostarlo sull'offset desiderato. Non so perché funzioni, ma per ora è la soluzione migliore che ho trovato.

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]; 
+3

Non funziona per me. Ho lo stesso problema –

+0

Questo ha funzionato perfettamente per me in iOS 9. Grazie. – vaticRite

+0

Funziona ma non voglio l'animazione –

0

ho dovuto ricorrere a

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

ma il problema BIG con esso è che inizia dalla parte superiore del testo e scorre fino alla fine ogni volta che si aggiunge al testo. Anche la soluzione di Mihai lo fa.

5

Ho appena notato che oggi. Nel mio caso il problema è apparentemente correlato alla visualizzazione del testo come il primo controllo nella vista. L'ho spostato in secondo piano nella struttura del documento (dopo un UILabel ad esempio) e l'offset è scomparso.

Molto probabilmente questo è fatto di proposito a causa della barra di navigazione nuovo comportamento in iOS7.

+1

OMG !!!!! Questa è la soluzione più stupida di sempre. Ma funziona! Basta capitato di avere un contentOffset nel mio UITextView di -64.0 –

+0

Grazie per averci salvato per un po 'dolorosa debug ... e lol mela – hhanesand

2

@answer opere di vidonism, ma questo è ancora meglio.

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

Vedi anche superiore commento di risposta accettata su questo question. Ciò probabilmente spiega il comportamento di un UIScrollView come prima vista secondaria di una vista principale di ViewController.
Non riesco a discretizzare se questo comportamento è previsto o un bug.

+0

Grazie signore ... questo è il tipo di risposta che cercavo, opere di ingegneria, ma ha nessuna resilienza, la maggior parte dei commenti su questo thread diventeranno deprecati nelle future versioni di IOS, non nelle tue. O almeno diventerà deprecato con errori di compilazione del tempo invece di un falso design e un noioso debugging. –

0

Nessuna delle risposte precedenti lavorato per me, perché ho avuto [textView setScrollEnabled:NO]. Quindi, ho finito con questo:

[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]; 
}); 
Problemi correlati