2013-05-23 12 views
5

Sto cercando di spostare un UIScrollView quando la tastiera nasconde un UITextField modificando le dimensioni utilizzando lo contentInsets come mostrato.Contenuto UIScrollView Inserti non funzionanti per Altezza tastiera

Tuttavia, non funziona per l'altezza della tastiera. L'altezza della tastiera arriva a 216, ma smette di scorrere solo nella posizione corretta se imposto il margine inferiore su 515 per la modalità verticale iPhone e 310 per la modalità orizzontale iPhone. Perché queste dimensioni sarebbero così diverse? Io non voglio hardcode questi valori arbitrari in

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.view.frame = self.parentViewController.view.frame; 

    [self.textView becomeFirstResponder]; 

    NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width); 

    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWasShown:) 
              name:UIKeyboardDidShowNotification 
              object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWillHide:) 
              name:UIKeyboardWillHideNotification 
              object:nil]; 
} 

- (void)keyboardWasShown:(NSNotification *)notification 
{ 
    if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone) { 

     // Step 1: Get the size of the keyboard. 
     CGFloat keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height; 

     // Step 2: Adjust the bottom content inset of your scroll view by the keyboard height. 
     UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardHeight, 0.0); 
     ((UIScrollView*)self.view).contentInset = contentInsets; 
     ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets; 

     // Step 3: Scroll the target text field into view. 
     CGRect aRect = self.view.frame; 
     aRect.size.height = aRect.size.height - keyboardHeight; 
     if (!CGRectContainsPoint(aRect, self.textView.frame.origin)) { 
      CGPoint scrollPoint = CGPointMake(0.0, self.textView.frame.origin.y - keyboardHeight); 
      [((UIScrollView*)self.view) setContentOffset:scrollPoint animated:YES]; 
     } 
    } 
} 

- (void) keyboardWillHide:(NSNotification *)notification { 
    UIEdgeInsets contentInsets = UIEdgeInsetsZero; 
    ((UIScrollView*)self.view).contentInset = contentInsets; 
    ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets; 
} 

Edit:.

Prima che la tastiera è aperta, a stampare questo fuori:

NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width); 

e stampe questo:

scrollview: 431.000000,320.000000, parent: 431.000000,320.000000 
+0

sta scorrendo bene senza tastiera, potrebbe essere possibile avere un'altezza superiore all'altezza della vista padre. –

+0

Sì. Scorre bene – Kristin

+0

voglio conoscere il frame di scrollview e il suo frame di visualizzazione genitore prima di aprire la tastiera. –

risposta

21

Penso che il problema principale è che è necessario utilizzare UIKeyboardFrameEndUserInfoKey invece di UIKeyboardFrameBeginUserInfoKey.

Detto questo, ho scritto una versione diversa di questo metodo che funziona anche se lo ScrollView non è collocato nella parte inferiore dello schermo e può funzionare meglio per voi:

Nota che uso self.activeTextField invece di self.textField.

// Called when the UIKeyboardDidShowNotification is sent. 
- (void)keyboardWasShown:(NSNotification*)aNotification 
{ 
    // Calculate the frame of the scrollview, in self.view's coordinate system 
    UIScrollView *scrollView = self.scrollView; 
    CGRect scrollViewRect  = [self.view convertRect:scrollView.frame fromView:scrollView.superview]; 

    // Calculate the frame of the keyboard, in self.view's coordinate system 
    NSDictionary* info   = [aNotification userInfo]; 
    CGRect kbRect    = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    kbRect      = [self.view convertRect:kbRect fromView:nil]; 

    // Figure out where the two frames overlap, and set the content offset of the scrollview appropriately 
    CGRect hiddenScrollViewRect = CGRectIntersection(scrollViewRect, kbRect); 
    if (!CGRectIsNull(hiddenScrollViewRect)) 
    { 
     UIEdgeInsets contentInsets  = UIEdgeInsetsMake(0.0, 0.0, hiddenScrollViewRect.size.height, 0.0); 
     scrollView.contentInset   = contentInsets; 
     scrollView.scrollIndicatorInsets = contentInsets; 
    } 

    [self scrollToActiveTextField]; 
} 

// Called when the UIKeyboardWillHideNotification is sent 
- (void)keyboardWillBeHidden:(NSNotification*)aNotification 
{ 
    self.scrollView.contentInset   = UIEdgeInsetsZero; 
    self.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero; 
} 

- (void)scrollToActiveTextField 
{ 
    if (self.activeTextField) 
    { 
     CGRect visibleRect = self.activeTextField.frame; 
     visibleRect  = [self.scrollView convertRect:visibleRect fromView:self.activeTextField.superview]; 
     visibleRect  = CGRectInset(visibleRect, 0.0f, -5.0f); 
     [self.scrollView scrollRectToVisible:visibleRect animated:YES]; 
    } 
} 
+0

In precedenza stavo cercando di manipolare il frame della scrollview per ottenere ciò, ma usando 'contentInset' rendeva il codice molto più semplice. – chakrit

+0

@chakrit Sono contento che questo ti abbia aiutato! – lnafziger

+0

Se ti stai strappando i capelli cercando di capire perché scrollRectToVisible non funziona, Apple sembra aver cambiato qualcosa (almeno con iOS 8 nel mio simulatore) dove se il rect è al di fuori del frame di UITableView, UICollectionView o UIScrollView, non si preoccupa neanche di cercare di scorrere verso di esso. Ad esempio, avevo chiamato [self.activeField convertRect: self.activeField.frame toView: self.tableView] ma avrebbe dovuto essere [self.activeField.superview convertRect: self.activeField.frame toView: self.tableView], quindi il rect.origin.x era uguale a 500, che è> 320, quindi non scorreva. –

0

imposta delegato del tuo scrollView come se stessi ovunque tu stia crating scrollview nel tuo codice

((UIScrollView*)self.view).delegate=self; 

poi

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.view.frame = self.parentViewController.view.frame; 

    [self.textView becomeFirstResponder]; 

    NSLog(@"scrollview: %f,%f, parent: %f,%f", self.view.frame.size.height, self.view.frame.size.width, self.parentViewController.view.frame.size.height, self.parentViewController.view.frame.size.width); 

    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWasShown:) 
              name:UIKeyboardDidShowNotification 
              object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWillHide:) 
              name:UIKeyboardWillHideNotification 
              object:nil]; 
} 

- (void)keyboardWasShown:(NSNotification *)notification 
{ 
    if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone) { 

     // Step 1: Get the size of the keyboard. 
     CGFloat keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height; 

     // Step 2: Adjust the bottom content inset of your scroll view by the keyboard height. 
     UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardHeight, 0.0); 
     ((UIScrollView*)self.view).contentInset = contentInsets; 
     ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets; 

     ((UIScrollView*)self.view).scrollEnabled=YES; 
    } 
} 

- (void) keyboardWillHide:(NSNotification *)notification { 
    UIEdgeInsets contentInsets = UIEdgeInsetsZero; 
    ((UIScrollView*)self.view).contentInset = contentInsets; 
    ((UIScrollView*)self.view).scrollIndicatorInsets = contentInsets; 
    [((UIScrollView*)self.view) setContentOffset:CGPointMake(0.0f, 0.0f) animated:TRUE]; 
    ((UIScrollView*)self.view).contentSize = CGSizeMake(((UIScrollView*)self.view).contentSize.width, ((UIScrollView*)self.view).contentSize.height); 
    ((UIScrollView*)self.view).scrollEnabled=NO; 

} 

#pragma mark - set scrollView content position 
-(void)scrollViewToCenterOfScreen:(UIView *)theView 
{ 
    CGFloat theViewY = theView.center.y; 
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame]; 
    CGFloat avaliableHeight = applicationFrame.size.height - 300; 
    CGFloat y = theViewY - avaliableHeight/2.0; 
    if(y<0) 
     y = 0; 
    [((UIScrollView*)self.view) setContentOffset:CGPointMake(0,y) animated:YES]; 
} 

#pragma -mark UITextField Delegate methods 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
{ 
    [self scrollViewToCenterOfScreen:textField]; 
    return YES; 
} 

Ora impostare delegato del campo di testo. Ogni volta che textFieldShouldBeginEditing: la tua scrollview si sposta automaticamente su quella. scrollViewToCenterOfScreen: metodo imposta la tua posizione scrollview in posizione textfiled.

Definisce definitivamente i contenuti del contenuto della schermata di scorrimento e setContentOffset. Per favore fatemi sapere se state ancora affrontando questo problema. Grazie

+0

Ciao Chandan, il problema non è che non imposti gli inset - posso impostarli manualmente. che non riesco a capire l'altezza corretta per impostarli da qualsiasi altro elemento sullo schermo.Io sto usando un numero arbitrario per l'altezza – Kristin

+0

Ciao Kristin, mi dispiace per la risposta in ritardo. Hai risolto il tuo problema? lo so, posso chiarire la cosa, grazie – chandan

+0

non l'ho ancora - lo stiamo ancora codificando – Kristin

Problemi correlati