Dokonywanie zwój UITableView gdy pole tekstowe jest zaznaczona

głosy
228

Po wielu próbach i błędach, daję się i zadać pytanie. Widziałem wiele osób z podobnymi problemami, ale nie może uzyskać wszystkie odpowiedzi do pracy w prawo.

Mam UITableViewktóry składa się z własnych komórek. Komórki są wykonane z 5 pól tekstowych obok siebie (coś w rodzaju siatki).

Kiedy próbuję przewijać i edytować komórek na dnie UITableView, nie uda się dostać moje komórki prawidłowo umieszczony nad klawiaturą.

Widziałem wiele odpowiedzi mówiące o zmieniających się widoków rozmiarach, itp ... ale żaden z nich nie pracował ładnie tak daleko.

Czy ktoś może wyjaśnić „prawo” sposób to zrobić z konkretnym przykładzie kodu?

Utwórz 27/02/2009 o 11:05
źródło użytkownik
W innych językach...                            


48 odpowiedzi

głosy
110

Jeśli używasz UITableViewController zamiast UIViewController, zostanie ona automatycznie zrobić.

Odpowiedział 21/09/2010 o 04:42
źródło użytkownik

głosy
89

Funkcja, która robi przewijanie może być znacznie prostsza:

- (void) textFieldDidBeginEditing:(UITextField *)textField {
    UITableViewCell *cell;

    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
    // Load resources for iOS 6.1 or earlier
        cell = (UITableViewCell *) textField.superview.superview;

    } else {
        // Load resources for iOS 7 or later
        cell = (UITableViewCell *) textField.superview.superview.superview; 
       // TextField -> UITableVieCellContentView -> (in iOS 7!)ScrollView -> Cell!
    }
    [tView scrollToRowAtIndexPath:[tView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

to jest to! Obliczenia w ogóle nie ma.

Odpowiedział 15/04/2009 o 13:21
źródło użytkownik

głosy
65

Robię coś bardzo podobnego To uniwersalne, nie ma potrzeby, aby obliczyć coś konkretnego o kodzie. Wystarczy sprawdzić uwag na temat kodu:

w MyUIViewController.h

@interface MyUIViewController: UIViewController <UITableViewDelegate, UITableViewDataSource>
{
     UITableView *myTableView;
     UITextField *actifText;
}

@property (nonatomic, retain) IBOutlet UITableView *myTableView;
@property (nonatomic, retain) IBOutlet UITextField *actifText;

- (IBAction)textFieldDidBeginEditing:(UITextField *)textField;
- (IBAction)textFieldDidEndEditing:(UITextField *)textField;

-(void) keyboardWillHide:(NSNotification *)note;
-(void) keyboardWillShow:(NSNotification *)note;

@end

w MyUIViewController.m

@implementation MyUIViewController

@synthesize myTableView;
@synthesize actifText;

- (void)viewDidLoad 
{
    // Register notification when the keyboard will be show
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(keyboardWillShow:)
                                          name:UIKeyboardWillShowNotification
                                          object:nil];

    // Register notification when the keyboard will be hide
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(keyboardWillHide:)
                                          name:UIKeyboardWillHideNotification
                                          object:nil];
}

// To be link with your TextField event "Editing Did Begin"
//  memoryze the current TextField
- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
    self.actifText = textField;
}

// To be link with your TextField event "Editing Did End"
//  release current TextField
- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
    self.actifText = nil;
}

-(void) keyboardWillShow:(NSNotification *)note
{
    // Get the keyboard size
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];

    // Detect orientation
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect frame = self.myTableView.frame;

    // Start animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // Reduce size of the Table view 
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
        frame.size.height -= keyboardBounds.size.height;
    else 
        frame.size.height -= keyboardBounds.size.width;

    // Apply new size of table view
    self.myTableView.frame = frame;

    // Scroll the table view to see the TextField just above the keyboard
    if (self.actifText)
      {
        CGRect textFieldRect = [self.myTableView convertRect:self.actifText.bounds fromView:self.actifText];
        [self.myTableView scrollRectToVisible:textFieldRect animated:NO];
      }

    [UIView commitAnimations];
}

-(void) keyboardWillHide:(NSNotification *)note
{
    // Get the keyboard size
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];

    // Detect orientation
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect frame = self.myTableView.frame;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // Increase size of the Table view 
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
        frame.size.height += keyboardBounds.size.height;
    else 
        frame.size.height += keyboardBounds.size.width;

    // Apply new size of table view
    self.myTableView.frame = frame;

    [UIView commitAnimations];
}

@end

Swift 1.2+ wersja:

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var activeText: UITextField!
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: Selector("keyboardWillShow:"),
            name: UIKeyboardWillShowNotification,
            object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: Selector("keyboardWillHide:"),
            name: UIKeyboardWillHideNotification,
            object: nil)
    }

    func textFieldDidBeginEditing(textField: UITextField) {
        activeText = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        activeText = nil
    }

    func keyboardWillShow(note: NSNotification) {
        if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            var frame = tableView.frame
            UIView.beginAnimations(nil, context: nil)
            UIView.setAnimationBeginsFromCurrentState(true)
            UIView.setAnimationDuration(0.3)
            frame.size.height -= keyboardSize.height
            tableView.frame = frame
            if activeText != nil {
                let rect = tableView.convertRect(activeText.bounds, fromView: activeText)
                tableView.scrollRectToVisible(rect, animated: false)
            }
            UIView.commitAnimations()
        }
    }

    func keyboardWillHide(note: NSNotification) {
        if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            var frame = tableView.frame
            UIView.beginAnimations(nil, context: nil)
            UIView.setAnimationBeginsFromCurrentState(true)
            UIView.setAnimationDuration(0.3)
            frame.size.height += keyboardSize.height
            tableView.frame = frame
            UIView.commitAnimations()
        }
    }
}
Odpowiedział 13/04/2010 o 15:46
źródło użytkownik

głosy
41

Miałem ten sam problem, ale zauważyłem, że pojawia się tylko w jednym widoku. Więc zacząłem szukać różnic w sterownikach.

I okazało się, że zachowanie przewijania jest w - (void)viewWillAppear:(BOOL)animatedod super instancji.

Więc należy wdrożyć tak:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // your code
}

I nie ma znaczenia, jeśli używasz UIViewControllerlub UITableViewController; Sprawdziłem to wstawiając UITableViewjako podrzędny z self.view w UIViewController. To było to samo zachowanie. Widok nie pozwala przewijać jeśli wywołanie [super viewWillAppear:animated];brakowało.

Odpowiedział 29/05/2011 o 01:42
źródło użytkownik

głosy
37

I może przegapić tego, jak nie przeczytać cały post tutaj, ale to, co wymyśliłem wydaje się zwodniczo prosta. I nie umieścić to przez magiel, testując w każdej sytuacji, ale wydaje się, że powinna działać dobrze.

po prostu dostosować contentInset z tableview przez wysokość klawiatury, a następnie wskaż komórkę do dołu:

- (void)keyboardWasShown:(NSNotification *)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    self.myTableView.contentInset = contentInsets;
    self.myTableView.scrollIndicatorInsets = contentInsets;

    [self.myTableView scrollToRowAtIndexPath:self.currentField.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

i oczywiście

- (void)keyboardWasHidden:(NSNotification *)aNotification
{
    [UIView animateWithDuration:.3 animations:^(void) 
    {
        self.myTableView.contentInset = UIEdgeInsetsZero;
        self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
    }];
}

Jest to zbyt proste? Am I czegoś brakuje? tak daleko, że pracuje dla mnie w porządku, ale jak już mówiłem, nie wprowadziły go przez magiel ...

Odpowiedział 18/08/2012 o 01:12
źródło użytkownik

głosy
35

Najprostszym rozwiązaniem Swift 3 , w przeliczeniu na roztwór Bartłomiej Semańczyk :

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

// MARK: Keyboard Notifications

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.2, animations: {
        // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    })
}
Odpowiedział 08/12/2016 o 13:26
źródło użytkownik

głosy
34

Jeśli można użyć UITableViewController, można uzyskać funkcjonalność za darmo. Czasami jednak nie jest to opcja, zwłaszcza jeśli potrzebujesz wiele widoków nie tylko UITableView.

Niektóre z rozwiązań przedstawionych tutaj nie działają na iOS ≥4, niektóre nie działają na iPadzie lub w trybie poziomym, niektóre nie działają dla klawiatur Bluetooth (jeżeli nie chcemy każdy przewijanie), niektóre nie pracować podczas przełączania między wieloma polami tekstowymi. Jeśli więc wybrać dowolne rozwiązanie, upewnij się, aby przetestować te przypadki. Jest to rozwiązanie, które wykorzystują stosowany w InAppSettingsKit :

- (void)_keyboardWillShow:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0
        NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"];
        if (!keyboardFrameValue) {
            keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
        }

        // Reduce the tableView height by the part of the keyboard that actually covers the tableView
        CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            windowRect = IASKCGRectSwap(windowRect);
        }
        CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
        }
        CGRect frame = _tableView.frame;
        frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute);

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = frame;
        [UIView commitAnimations];

        UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview;
        NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell];

        // iOS 3 sends hide and show notifications right after each other
        // when switching between textFields, so cancel -scrollToOldPosition requests
        [NSObject cancelPreviousPerformRequestsWithTarget:self];

        [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
}

- (void) scrollToOldPosition {
  [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)_keyboardWillHide:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = self.view.bounds;
        [UIView commitAnimations];

        [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1];
    }
}   

Poniżej znajduje się pełny kod klasy w InAppSettingsKit. By to sprawdzić, należy użyć „Complete List” okienko dziecko, gdzie można przetestować scenariuszy wymienionych powyżej.

Odpowiedział 13/12/2010 o 17:01
źródło użytkownik

głosy
34

Chyba wymyślić rozwiązanie, aby dopasować zachowanie aplikacji Apple.

Po pierwsze, w swojej viewWillAppear: subskrybowania powiadomień klawiatury, więc nie wiadomo, kiedy klawiatura będzie pokazywać i ukrywać, a system pokaże Ci rozmiar klawiatury, ale nie”zapomni wyrejestrować w viewWillDisappear :.

[[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(keyboardWillShow:)
           name:UIKeyboardWillShowNotification
         object:nil];
[[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(keyboardWillHide:)
           name:UIKeyboardWillHideNotification
         object:nil];

Wdrożenie metody podobne do dołu, tak aby dostosować rozmiar swojej Tableview dopasować widoczny obszar raz pokazuje klawiaturowych. Tutaj mam osobno śledzenia stanu klawiaturze więc mogę wybrać, kiedy ustawić tableView z powrotem do pełnej wysokości sam, ponieważ masz te powiadomienia o każdej zmianie pola. Nie zapomnij do wdrożenia keyboardWillHide: i wybrać gdzieś ustalić rozmiar Tableview.

-(void) keyboardWillShow:(NSNotification *)note
{
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
    keyboardHeight = keyboardBounds.size.height;
    if (keyboardIsShowing == NO)
    {
        keyboardIsShowing = YES;
        CGRect frame = self.view.frame;
        frame.size.height -= keyboardHeight;

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:0.3f];
        self.view.frame = frame;
        [UIView commitAnimations];
    }
}

Teraz tutaj jest nieco przewijanie, możemy wypracować kilka rozmiarów, potem zobaczymy, gdzie jesteśmy w widocznym miejscu i ustaw rect chcemy przewinąć do być albo pół widok powyżej lub poniżej środkowej części pola tekstowego w oparciu gdzie to jest w widoku. W tym przypadku mamy tablicę UITextFields i enum, który śledzi nimi, tak pomnożenie rowHeight przez liczbę rzędów daje nam rzeczywiste przesunięcie ramki w tym widoku zewnętrznym.

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect frame = textField.frame;
    CGFloat rowHeight = self.tableView.rowHeight;
    if (textField == textFields[CELL_FIELD_ONE])
    {
        frame.origin.y += rowHeight * CELL_FIELD_ONE;
    }
    else if (textField == textFields[CELL_FIELD_TWO])
    {
        frame.origin.y += rowHeight * CELL_FIELD_TWO;
    }
    else if (textField == textFields[CELL_FIELD_THREE])
    {
        frame.origin.y += rowHeight * CELL_FIELD_THREE;
    }
    else if (textField == textFields[CELL_FIELD_FOUR])
    {
        frame.origin.y += rowHeight * CELL_FIELD_FOUR;
    }
    CGFloat viewHeight = self.tableView.frame.size.height;
    CGFloat halfHeight = viewHeight / 2;
    CGFloat midpoint = frame.origin.y + (textField.frame.size.height / 2);
    if (midpoint < halfHeight)
    {
        frame.origin.y = 0;
        frame.size.height = midpoint;
    }
    else
    {
        frame.origin.y = midpoint;
        frame.size.height = midpoint;
    }
    [self.tableView scrollRectToVisible:frame animated:YES];
}

To wydaje się działać całkiem ładnie.

Odpowiedział 23/03/2009 o 02:49
źródło użytkownik

głosy
22

Najprostszym rozwiązaniem dla Swift :

override func viewDidLoad() {
    super.viewDidLoad()

    searchBar?.becomeFirstResponder()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillHide(_:)), name: UIKeyboardDidHideNotification, object: nil)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue.size.height {
            tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    UIView.animateWithDuration(0.2, animations: { self.table_create_issue.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) })
    // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
    }
Odpowiedział 25/08/2015 o 06:42
źródło użytkownik

głosy
6

Mam nadzieję, że wy już mam rozwiązanie przeczytaniu wszystkich tych. Ale znalazłem moje rozwiązanie w sposób następujący. Oczekuję, że masz już komórkę z UITextField. Więc po prostu zachować na przygotowanie indeks wiersz do zmiennej pola tekstowego.

cell.textField.tag = IndexPath.row;

Utwórz activeTextField, wystąpienie UITextFieldo zasięgu globalnym, jak poniżej:

@interface EditViewController (){

    UITextField *activeTextField;

}

Więc teraz po prostu skopiować wkleić mój kod na końcu. A także nie zapomnij dodaćUITextFieldDelegate

#pragma mark - TextField Delegation

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{

    activeTextField = textField;

    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField{

    activeTextField = nil;

}

rejestry klawiatura notifications

#pragma mark - Keyboard Activity

- (void)registerForKeyboardNotifications

{

    [[NSNotificationCenter defaultCenter] addObserver:self

                                         selector:@selector(keyboardWasShown:)

                                             name:UIKeyboardDidShowNotification object:nil];



    [[NSNotificationCenter defaultCenter] addObserver:self

                                         selector:@selector(keyboardWillBeHidden:)

                                             name:UIKeyboardWillHideNotification object:nil];



}

Uchwyty klawiatury Notifications:

Wywoływana, gdy UIKeyboardDidShowNotificationjest wysłana.

- (void)keyboardWasShown:(NSNotification*)aNotification

{

    NSDictionary* info = [aNotification userInfo];

    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);

    [self.tableView setContentInset:contentInsets];

    [self.tableView setScrollIndicatorInsets:contentInsets];

    NSIndexPath *currentRowIndex = [NSIndexPath indexPathForRow:activeTextField.tag inSection:0];

    [self.tableView scrollToRowAtIndexPath:currentRowIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];

}

Wywoływana, gdy UIKeyboardWillHideNotificationzostaje wysłany

- (void)keyboardWillBeHidden:(NSNotification*)aNotification

{

    UIEdgeInsets contentInsets = UIEdgeInsetsZero;

    [self.tableView setContentInset:contentInsets];

    [self.tableView setScrollIndicatorInsets:contentInsets];

}

Teraz jedna rzecz pozostaje, zadzwoń do registerForKeyboardNotificationsmetody w celu ViewDidLoadmetody w następujący sposób:

- (void)viewDidLoad {

    [super viewDidLoad];

    // Registering keyboard notification

    [self registerForKeyboardNotifications];

    // Your codes here...

}

Skończysz, nadzieję, że textFieldsnie będzie już ukryte przez klawiaturę.

Odpowiedział 03/01/2015 o 21:36
źródło użytkownik

głosy
6

Łączenie i wypełnienie luki z kilku odpowiedzi (w szczególności Ortwin Gentz, łatwość 98013) oraz inne stanowisko, to będzie działać po wyjęciu z pudełka do SDK 4.3 na iPada w trybie pionowym lub poziomym:

@implementation UIView (FindFirstResponder)
- (UIResponder *)findFirstResponder
{
  if (self.isFirstResponder) {        
    return self;     
  }

  for (UIView *subView in self.subviews) {
    UIResponder *firstResponder = [subView findFirstResponder];
    if (firstResponder != nil) {
      return firstResponder;
    }
  }

  return nil;
}
@end

@implementation MyViewController

- (UIResponder *)currentFirstResponder {
  return [self.view findFirstResponder];
}

- (IBAction)editingEnded:sender {
  [sender resignFirstResponder];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
  [textField resignFirstResponder];
  return NO;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  UITableViewCell *cell = (UITableViewCell*) [[textField superview] superview];
  [_tableView scrollToRowAtIndexPath:[_tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)keyboardWillShow:(NSNotification*)notification {
  if ([self currentFirstResponder] != nil) {
    NSDictionary* userInfo = [notification userInfo];

    // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0
    NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"];
    if (!keyboardFrameValue) {
      keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
    }

    // Reduce the tableView height by the part of the keyboard that actually covers the tableView
    CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
    CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
    CGRect frame = _tableView.frame;
    if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
      windowRect = CGRectMake(windowRect.origin.y, windowRect.origin.x, windowRect.size.height, windowRect.size.width);
      viewRectAbsolute = CGRectMake(viewRectAbsolute.origin.y, viewRectAbsolute.origin.x, viewRectAbsolute.size.height, viewRectAbsolute.size.width);
    }
    frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    _tableView.frame = frame;
    [UIView commitAnimations];

    UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview;
    NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell];

    // iOS 3 sends hide and show notifications right after each other
    // when switching between textFields, so cancel -scrollToOldPosition requests
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    _topmostRowBeforeKeyboardWasShown = [[_tableView indexPathsForVisibleRows] objectAtIndex:0];
    [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
  }
}

- (void) scrollToOldPosition {
  [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)keyboardWillHide:(NSNotification*)notification {
  if ([self currentFirstResponder] != nil) {

    NSDictionary* userInfo = [notification userInfo];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    _tableView.frame = self.view.bounds;
    [UIView commitAnimations];

    [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1];
  }
}   

@end
Odpowiedział 03/08/2011 o 03:35
źródło użytkownik

głosy
5

Moje podejście:

Po raz pierwszy podklasę UITextField i dodać właściwość indexPath. W cellFor ... Metoda I przekazać własność indexPath.

Potem dodać następujący kod:

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:textField.indexPath];

CGPoint cellPoint = [cell convertPoint:textField.center toView:self.tableView];
[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, cellPoint.y-50);}];

do textFieldShould / WillBegin ... itp.

Po zniknięciu Klawiatura trzeba odwrócić go z:

[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, 0);}];
Odpowiedział 29/09/2012 o 13:03
źródło użytkownik

głosy
4

Użyj UITextField's delegatemetody:

Szybki

func textFieldShouldBeginEditing(textField: UITextField) -> bool {
  let txtFieldPosition = textField.convertPoint(textField.bounds.origin, toView: yourTableViewHere)
  let indexPath = yourTablViewHere.indexPathForRowAtPoint(txtFieldPosition)
  if indexPath != nil {
     yourTablViewHere.scrollToRowAtIndexPath(indexPath!, atScrollPosition: .Top, animated: true)
  }
  return true
}

Cel C

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
  CGPoint txtFieldPosition = [textField convertPoint:CGPointZero toView: yourTablViewHere];
  NSLog(@"Begin txtFieldPosition : %@",NSStringFromCGPoint(txtFieldPosition));
  NSIndexPath *indexPath = [yourTablViewHere indexPathForRowAtPoint:txtFieldPosition];

  if (indexPath != nil) {
     [yourTablViewHere scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
  }
  return YES;
}
Odpowiedział 20/03/2015 o 07:00
źródło użytkownik

głosy
4

Prawidłowa odpowiedź to odpowiedź Sam Ho:

„Jeśli używasz UITableViewController zamiast UIViewController, zostanie ona automatycznie zrobić.”.

Wystarczy upewnić się, aby podłączyć UITableView do nieruchomości Tableview z UITableViewController (tak na przykład nie dodawaj go jako podrzędny z widokiem na własność UITableViewController).

Upewnij się także, aby ustawić właściwość AutoresizingMask swojego UITableView do FlexibleHeight

Odpowiedział 09/12/2010 o 11:28
źródło użytkownik

głosy
4

Jeśli używasz Three20, a następnie użyć autoresizesForKeyboardwłasności. Wystarczy ustawić w Państwa zdanie kontrolera -initWithNibName:bundlemetody

self.autoresizesForKeyboard = YES

To zajmuje:

  1. Nasłuchiwanie powiadomień klawiatury i dostosowanie ramkę widoku stołu
  2. Przewijanie do pierwszego odpowiadającego

Sporządzono i gotowe.

Odpowiedział 21/09/2010 o 14:19
źródło użytkownik

głosy
4

Powiadomienia klawiatura działa, ale przykładowy kod dla Apple, który zakłada, że ​​widok przewijania jest widok z okna głównego. Zwykle nie jest to przypadek. Trzeba zrekompensować barów karcie itp, aby uzyskać prawo przesunięcia.

Jest to łatwiejsze niż się wydaje. Oto kod używam w UITableViewController. Posiada dwie zmienne instancji hiddenRect i keyboardShown.

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
    if (keyboardShown)
        return;

    NSDictionary* info = [aNotification userInfo];

    // Get the frame of the keyboard.
    NSValue *centerValue = [info objectForKey:UIKeyboardCenterEndUserInfoKey];
    NSValue *boundsValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
    CGPoint keyboardCenter = [centerValue CGPointValue];
    CGRect keyboardBounds = [boundsValue CGRectValue];
    CGPoint keyboardOrigin = CGPointMake(keyboardCenter.x - keyboardBounds.size.width / 2.0,
                                         keyboardCenter.y - keyboardBounds.size.height / 2.0);
    CGRect keyboardScreenFrame = { keyboardOrigin, keyboardBounds.size };


    // Resize the scroll view.
    UIScrollView *scrollView = (UIScrollView *) self.tableView;
    CGRect viewFrame = scrollView.frame;
    CGRect keyboardFrame = [scrollView.superview convertRect:keyboardScreenFrame fromView:nil];
    hiddenRect = CGRectIntersection(viewFrame, keyboardFrame);

    CGRect remainder, slice;
    CGRectDivide(viewFrame, &slice, &remainder, CGRectGetHeight(hiddenRect), CGRectMaxYEdge);
    scrollView.frame = remainder;

    // Scroll the active text field into view.
    CGRect textFieldRect = [/* selected cell */ frame];
    [scrollView scrollRectToVisible:textFieldRect animated:YES];

    keyboardShown = YES;
}


// Called when the UIKeyboardDidHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
    // Reset the height of the scroll view to its original value
    UIScrollView *scrollView = (UIScrollView *) self.tableView;
    CGRect viewFrame = [scrollView frame];
    scrollView.frame = CGRectUnion(viewFrame, hiddenRect);

    keyboardShown = NO;
}
Odpowiedział 11/07/2009 o 23:01
źródło użytkownik

głosy
4

W przypadku korzystania z UITableView, aby umieścić pól tekstowych ( z Jeffem Lamarche ), można tylko przewijać tableview stosując metodę delegata jak tak.

(Uwaga: moje pola tekstowe są przechowywane w tablicy z tym samym indeksem jak tam wiersza w tableview)

- (void) textFieldDidBeginEditing:(UITextField *)textField
    {

        int index;
        for(UITextField *aField in textFields){

            if (textField == aField){
                index = [textFields indexOfObject:aField]-1;
            }
        }

         if(index >= 0) 
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];

        [super textFieldDidBeginEditing:textField];
    }
Odpowiedział 01/05/2009 o 07:09
źródło użytkownik

głosy
3

Bardziej strumień wyłożone rozwiązaniem. To wymyka się metodami delegatów UITextField, więc nie wymaga ingerować w / zawiadomień UIKeyboard.

notatki z wdrożenia

kSettingsRowHeight - wysokość w UITableViewCell.

offsetTarget i offsetThreshold są BAED off kSettingsRowHeight. Jeśli używasz innego wysokość wiersza, należy ustawić te wartości do punktu rekreacyjnego y. [Alt: obliczyć rzędu przesunięte w inny sposób.]

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat offsetTarget    = 113.0f; // 3rd row
CGFloat offsetThreshold = 248.0f; // 6th row (i.e. 2nd-to-last row)

CGPoint point = [self.tableView convertPoint:CGPointZero fromView:textField];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

CGRect frame = self.tableView.frame;
if (point.y > offsetThreshold) {
    self.tableView.frame = CGRectMake(0.0f,
                      offsetTarget - point.y + kSettingsRowHeight,
                      frame.size.width,
                      frame.size.height);
} else if (point.y > offsetTarget) {
    self.tableView.frame = CGRectMake(0.0f,
                      offsetTarget - point.y,
                      frame.size.width,
                      frame.size.height);
} else {
    self.tableView.frame = CGRectMake(0.0f,
                      0.0f,
                      frame.size.width,
                      frame.size.height);
}

[UIView commitAnimations];

return YES;

}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

CGRect frame = self.tableView.frame;
self.tableView.frame = CGRectMake(0.0f,
                  0.0f,
                  frame.size.width,
                  frame.size.height);

[UIView commitAnimations];

return YES;

}

Odpowiedział 04/08/2009 o 08:18
źródło użytkownik

głosy
3

Wpadłem na coś podobnego problemu (chciałem ekran podobny do settings.app iPhone z gronem edycji komórki ułożone na na drugim) i okazało się, że takie podejście działa dobrze:

uitextfields przesuwania się, aby uniknąć

Odpowiedział 27/02/2009 o 15:17
źródło użytkownik

głosy
2

Przykładem w Swift, stosując dokładnie punkcie pola tekstowego z Get indexPath od UITextField w UITableViewCell z Swift :

func textFieldDidBeginEditing(textField: UITextField) {
    let pointInTable = textField.convertPoint(textField.bounds.origin, toView: self.accountsTableView)
    let textFieldIndexPath = self.accountsTableView.indexPathForRowAtPoint(pointInTable)
    accountsTableView.scrollToRowAtIndexPath(textFieldIndexPath!, atScrollPosition: .Top, animated: true)
}
Odpowiedział 21/05/2015 o 06:34
źródło użytkownik

głosy
2

Bardzo interesujący wątek dyskusji, również w obliczu tego samego problemu może być gorszy, ponieważ

  1. Używałem komórkę niestandardowej i pole tekstowe, które jest w środku.
  2. Musiałem użyć UIViewController aby spełnić moje wymagania, więc nie mogę skorzystać z UITableViewController.
  3. Miałem charakterystyczne filtr / sortowanie w mojej komórce tabeli, tj ur komórki ciągle się zmienia i śledzenie na indexpath i wszystko nie pomoże.

Więc czytaj wątków tutaj i wdrożone moją wersję, która pomogła mi w winduje moje zawartość w iPadzie w poziomym trybie. Oto kod (to nie jest głupi dowód i wszystko, ale to naprawić mój problem) Po pierwsze trzeba mieć u delegata w swojej klasie niestandardowych komórki, która zaczyna się na edycji, wysyła pole tekstowe ur viewcontroller i ustawić activefield = theTextField tam

// wdrożyć UCHWYT KRAJOBRAZU tylko tryb

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect aRect = myTable.frame;

    CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);

    aRect.size.height -= kbSize.height+50;
// This will the exact rect in which your textfield is present
        CGRect rect =  [myTable convertRect:activeField.bounds fromView:activeField];
// Scroll up only if required
    if (!CGRectContainsPoint(aRect, rect.origin) ) {


            [myTable setContentOffset:CGPointMake(0.0, rect.origin.y) animated:YES];

    }


}

// Wywoływana gdy UIKeyboardWillHideNotification jest wysyłany

- (void)keyboardWillHide:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    myTable.contentInset = contentInsets;
    myTable.scrollIndicatorInsets = contentInsets;
    NSDictionary* info = [aNotification userInfo];
    CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);
    CGRect bkgndRect = activeField.superview.frame;
    bkgndRect.size.height += kbSize.height;
    [activeField.superview setFrame:bkgndRect];
    [myTable setContentOffset:CGPointMake(0.0, 10.0) animated:YES];
}

-anoop4real

Odpowiedział 17/07/2012 o 18:11
źródło użytkownik

głosy
2

Ten soluton pracuje dla mnie, proszę zwrócić uwagę na linię

[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];

Można zmienić wartość 160, aby dopasować go pracować z wami

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = activeField.superview.frame;
                        bkgndRect.size.height += kbSize.height;
     [activeField.superview setFrame:bkgndRect];
     [tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
   activeField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
 {
     activeField = nil;
 }
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    tableView.contentInset = contentInsets;
    tableView.scrollIndicatorInsets = contentInsets;
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = activeField.superview.frame;
    //bkgndRect.size.height += kbSize.height;
    [activeField.superview setFrame:bkgndRect];
    [tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}
Odpowiedział 02/12/2011 o 19:28
źródło użytkownik

głosy
2

Skoro masz pól tekstowych w tabeli, najlepszym sposobem jest naprawdę, aby zmienić rozmiar tabeli - trzeba ponownie ustawić tableView.frame być mniejsze w wysokości od wielkości klawiatury (myślę, że około 165 pikseli), a następnie rozwiń ją, gdy klawiatura zostaje odrzucona.

Opcjonalnie można również wyłączyć interakcję użytkownika dla Tableview w tym czasie, jak również, jeśli nie chcesz przewijanie użytkownika.

Odpowiedział 28/02/2009 o 19:37
źródło użytkownik

głosy
1

Mała wariacja z Swift 4.2 ...

Na moim UITableView miałem wiele odcinków, ale musiałem unikać pływający efekt nagłówka więc użyłem „ dummyViewHeight podejście” jak widać gdzieś tutaj na przepełnienie stosu ... Więc to jest moje rozwiązanie tego problemu (działa również na klawiaturze + sugestie Pasek +):

Zadeklarować ją jako stałą klasy:

let dummyViewHeight: CGFloat = 40.0

Następnie

override func viewDidLoad() {
    super.viewDidLoad()
    //... some stuff here, not needed for this example

    // Create non floating header
    tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: dummyViewHeight))
    tableView.contentInset = UIEdgeInsets(top: -dummyViewHeight, left: 0, bottom: 0, right: 0)

    addObservers()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    removeObservers()
}

A tu cała magia ...

@objc func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let keyboardHeight = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue.size.height
        tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
        tableView.contentInset = UIEdgeInsets(top: -dummyViewHeight, left: 0, bottom: keyboardHeight, right: 0)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.25) {
        self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: self.dummyViewHeight))
        self.tableView.contentInset = UIEdgeInsets(top: -self.dummyViewHeight, left: 0, bottom: 0, right: 0)
    }
}
Odpowiedział 08/10/2018 o 10:45
źródło użytkownik

głosy
1

w viewDidLoad

-(void)viewdidload{

[super viewdidload];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

    -(void)keyboardWillChange:(NSNotification*)sender{

        NSLog(@"keyboardwillchange sender %@",sender);

float margin=0  // set your own topmargin


        CGFloat originY = [[sender.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;


        if (originY >= self.view.frame.size.height){

            NSLog(@"keyboardclose");



            [tb_ setFrame:CGRectMake(0, margin, self.view.frame.size.width, self.view.frame.size.height-margin)];

        }else{

            NSLog(@"keyobard on");

            float adjustedHeight = self.view.frame.size.height - margin - (self.view.frame.size.height-originY);

            [tb_ setFrame:CGRectMake(0, margin, self.view.frame.size.width, adjustedHeight)];
        }







    }
Odpowiedział 12/02/2016 o 09:14
źródło użytkownik

głosy
1

Używam tych i działają jak urok:

BSKeyboardControls - BSKeyboardControls github

TPKeyboardAvoiding - TPKeyboardAvoiding github

Odpowiedział 13/02/2014 o 09:30
źródło użytkownik

głosy
1

Używam tego często w moich projektach. To rozwiązanie działa z scrollviews, tableviews lub collectionviews i jest łatwy w konfiguracji. To również automatycznie haki „next” przycisków na klawiaturze, aby przełączyć się po polach tekstowych.

Sprawdź to tutaj

Odpowiedział 12/02/2014 o 21:27
źródło użytkownik

głosy
1

rzucę moje rozwiązanie (lub QuickDialog, że jest) do kapelusza. Zasadniczo czekać do animowania do przewijania. Byłoby miło, aby uzyskać JIT animacji klawiatury zamiast numeru magicznego.

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    if (textField == self.emailTextField) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 50 * USEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
        });
    }
}
Odpowiedział 28/01/2014 o 19:05
źródło użytkownik

głosy
1

Łatwe i szybkie rozwiązanie.

Po prostu przejdź do właściwej komórki ilekroć zdarza przewijanie

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView 

Zakładając wiem tabelę teraz jest w tym trybie „_keepMyCellOnTop” i wiem wybraną komórkę „_selectedCellIndex” lub przejść do wybranej komórki

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{

    if (_keepMyCellOnTop)
    {
        [self.tableView scrollToRowAtIndexPath:_selectedCellIndex atScrollPosition:UITableViewScrollPositionTop animated:NO];
    }
}

Zapobiegnie to przewijanie.

Umieszczenie kodu w -(void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView spowoduje przewijania w górę iw dół

Odpowiedział 31/12/2013 o 13:37
źródło użytkownik

głosy
1

Właśnie taki problem rozwiązany przez siebie po tym mowa masę rozwiązań znalezionych przez Google i przepełnienie stosu.

Po pierwsze, należy upewnić się, że masz założyć IBOutlet swojego UIScrollView, wtedy proszę uważnie zapoznać się firmy Apple Doc: Zarządzanie klawiatury . W końcu, jeśli można przewijać tło, ale klawiatura nadal obejmuje pola tekstowe, proszę spojrzeć na ten fragment kodu:

// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;

if (aRect.size.height < activeField.frame.origin.y+activeField.frame.size.height) {

    CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y+activeField.frame.size.height-aRect.size.height);

    [scrollView setContentOffset:scrollPoint animated:YES];

Główną różnicą pomiędzy tym kawałku i kłamstwa Apple'a w razie choroby. Wierzę, obliczanie odległości przewijania i stanu czy pole tekstowe objęte klawiaturze nie są dokładne Apple, więc zrobiłem mój modyfikacji jak wyżej.

Daj znać czy działa

Odpowiedział 18/08/2012 o 11:10
źródło użytkownik

głosy
1

Oto jak zrobiłem tę pracę, która jest mieszaniną Sam Ho i odpowiedzi Marcela W, a niektóre z moich własnych poprawek wprowadzonych do mojego kodu bzdura. I był przy użyciu UITableViewController. Tabela teraz zmienia rozmiar poprawnie kiedy klawiatura jest pokazane.

1) viewDidLoadI dodaje:

self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

2) I zapomniał zadzwonić do superodpowiedników w viewWillAppeari awakeFromNib. Dodałem te widok.

Odpowiedział 26/07/2012 o 18:18
źródło użytkownik

głosy
1

Jeśli UITableView jest zarządzany przez podklasy UITableViewController i nie UITableView, a delegat pole tekstowe jest UITableViewController, powinien zarządzać przewijanie automatycznie - wszystkie te inne komentarze są bardzo trudne do zrealizowania w praktyce.

Na dobry przykład patrz projekt przykładowy kod Apple: TaggedLocations.

Można zobaczyć, że przewija się automatycznie, ale nie wydaje się być dowolny kod, który to robi. Projekt ten ma również zwyczaj Table View komórki, więc jeśli budować swoją aplikację z nim jako przewodnik, należy uzyskać pożądany rezultat.

Odpowiedział 05/03/2012 o 07:09
źródło użytkownik

głosy
1

Inna prosta metoda (działa tylko z jednej sekcji)

//cellForRowAtIndexPath
UItextField *tf;
[cell addSubview:tf];
tf.tag = indexPath.row;
tf.delegate = self;

//textFieldDidBeginEditing:(UITextField *)text
[[self.tableView scrollToRowsAtIndexPath:[NSIndexPath indexPathForRow:text.tag in section:SECTIONINTEGER] animated:YES];
Odpowiedział 23/11/2011 o 17:25
źródło użytkownik

głosy
1

Więc po godzinach wyczerpującej pracy stara się korzystać z tych obecnych rozwiązań (i całkowicie braku) I wreszcie, co działa dobrze, a zaktualizowany ich do korzystania z nowych bloków animacji. Moja odpowiedź jest w całości oparty na odpowiedź Ortwin jest powyżej .

Więc niezależnie od powodu powyższy kod po prostu nie działa dla mnie. Moje menu wydawała się dość podobna do innych, ale może dlatego, że był na iPada lub 4.3 ... bez pomysłu. To był jakiś głupi robi matematyki i strzelanie moje tableview na ekranie.

Zobacz wynik końcowy mojego rozwiązania: http://screencast.com/t/hjBCuRrPC (proszę ignorować zdjęcie :-P).

Więc poszedłem z GIST, co Ortwin robił, ale zmienił się, jak to było jakiejś matematyki zsumować origin.y & size.height mojego widoku tabeli z wysokości klawiatury. Kiedy odjąć wysokość okna z tego wyniku, to mówi mi, ile mam skrzyżowanie dzieje. Jeśli jej większa niż 0 (czyli istnieje pewna część) wykonuję animację wysokości ramy.

Ponadto istniały pewne przerysowanie kwestie, które zostały rozwiązane przez 1) czeka, aby przewinąć do celi aż animacja została wykonana i 2) za pomocą opcji UIViewAnimationOptionBeginFromCurrentState gdy ukrywanie klawiatury.

Kilka rzeczy, aby pamiętać.

  • _topmostRowBeforeKeyboardWasShown & _originalFrame są zmienne instancji zadeklarowane w nagłówku.
  • self.guestEntryTableView jest moim tableView (jestem w zewnętrznym pliku)
  • IASKCGRectSwap jest metoda Ortwin za przerzucanie współrzędne ramie
  • I tylko aktualizować wysokość Tableview jeżeli co najmniej 50px z nim będzie widać
  • Ponieważ nie jestem w UIViewController nie mam self.view, więc po prostu powrócić do swojej pierwotnej tableView ramie

Znowu, nie byłoby zdobyć w pobliżu tej odpowiedzi gdybym Ortwin nie przewiduje sedno niego. Oto kod:

- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeTextField = textField;

    if ([self.guestEntryTableView indexPathsForVisibleRows].count) {
        _topmostRowBeforeKeyboardWasShown = (NSIndexPath*)[[self.guestEntryTableView indexPathsForVisibleRows] objectAtIndex:0];
    } else {
        // this should never happen
        _topmostRowBeforeKeyboardWasShown = [NSIndexPath indexPathForRow:0 inSection:0];
        [textField resignFirstResponder];
    }
}

- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
    self.activeTextField = nil;
}

- (void)keyboardWillShow:(NSNotification*)notification {
    NSDictionary* userInfo = [notification userInfo];

    NSValue* keyboardFrameValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    // Reduce the tableView height by the part of the keyboard that actually covers the tableView
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
    CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
    CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
    if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation ) {
        windowRect = IASKCGRectSwap(windowRect);
        viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
        keyboardFrame = IASKCGRectSwap(keyboardFrame);
    }

    // fix the coordinates of our rect to have a top left origin 0,0
    viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);

    CGRect frame = self.guestEntryTableView.frame;
    _originalFrame = self.guestEntryTableView.frame;

    int remainder = (viewRectAbsolute.origin.y + viewRectAbsolute.size.height + keyboardFrame.size.height) - windowRect.size.height;

    if (remainder > 0 && !(remainder > frame.size.height + 50)) {
        frame.size.height = frame.size.height - remainder;
        float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        [UIView animateWithDuration: duration
                        animations:^{
                            self.guestEntryTableView.frame = frame;
                        }
                        completion:^(BOOL finished){
                            UITableViewCell *textFieldCell = (UITableViewCell*) [[self.activeTextField superview] superview];
                            NSIndexPath *textFieldIndexPath = [self.guestEntryTableView indexPathForCell:textFieldCell];
                            [self.guestEntryTableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
                        }];
    }

}

- (void)keyboardWillHide:(NSNotification*)notification {
    NSDictionary* userInfo = [notification userInfo];
    float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    [UIView animateWithDuration: duration
                          delay: 0.0
                        options: (UIViewAnimationOptionBeginFromCurrentState)
                     animations:^{
                         self.guestEntryTableView.frame = _originalFrame;
                     }
                     completion:^(BOOL finished){
                         [self.guestEntryTableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
                     }];

}   

#pragma mark CGRect Utility function
CGRect IASKCGRectSwap(CGRect rect) {
    CGRect newRect;
    newRect.origin.x = rect.origin.y;
    newRect.origin.y = rect.origin.x;
    newRect.size.width = rect.size.height;
    newRect.size.height = rect.size.width;
    return newRect;
}

CGRect FixOriginRotation(CGRect rect, UIInterfaceOrientation orientation, int parentWidth, int parentHeight) {
    CGRect newRect;
    switch(orientation)
    {
        case UIInterfaceOrientationLandscapeLeft:
            newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), rect.origin.y, rect.size.width, rect.size.height);
            break;
        case UIInterfaceOrientationLandscapeRight:
            newRect = CGRectMake(rect.origin.x, parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
            break;
        case UIInterfaceOrientationPortrait:
            newRect = rect;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
            break;
    }
    return newRect;
}
Odpowiedział 18/07/2011 o 09:45
źródło użytkownik

głosy
1

Próbowałem prawie takie samo podejście i podszedł z kodem prostszy i mniejszy za to samo. I stworzył IBOutlet iTextView i związane z UITextView w IB.

 -(void)keyboardWillShow:(NSNotification *)notification
    {
        NSLog(@"Keyboard");
        CGRect keyFrame = [[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];

        [UIView beginAnimations:@"resize view" context:nil];
        [UIView setAnimationCurve:1];
        [UIView setAnimationDuration:1.0];
        CGRect frame = iTableView.frame;
        frame.size.height = frame.size.height -  keyFrame.size.height;
        iTableView.frame = frame;
        [iTableView scrollRectToVisible:frame animated:YES];
        [UIView commitAnimations];

    }
Odpowiedział 13/05/2011 o 06:00
źródło użytkownik

głosy
1

Działa to doskonale, a na iPadzie też.

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{

    if(textField == textfield1){
            [accountName1TextField becomeFirstResponder];
        }else if(textField == textfield2){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield3 becomeFirstResponder];

        }else if(textField == textfield3){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield4 becomeFirstResponder];

        }else if(textField == textfield4){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield5 becomeFirstResponder];

        }else if(textField == textfield5){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield6 becomeFirstResponder];

        }else if(textField == textfield6){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield7 becomeFirstResponder];

        }else if(textField == textfield7){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield8 becomeFirstResponder];

        }else if(textField == textfield8){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield9 becomeFirstResponder];

        }else if(textField == textfield9){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:7 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textField resignFirstResponder];
        }
Odpowiedział 23/10/2010 o 08:11
źródło użytkownik

głosy
0

Właśnie odkryłem kolejny błąd podczas korzystania UITableViewController. To nie przewijał się automatycznie, gdy klawiatura nie pokazał. Zauważyłem, że to z powodu contentInsetAdjustmentBehavior = .never na UITableView.

Odpowiedział 03/07/2019 o 21:30
źródło użytkownik

głosy
0

Rozwiązanie dla Swift 3-4 z animacjami i zmiana ramki klawiatury:

Najpierw utwórz Bool:

// MARK: - Private Properties
private var isKeyboardShowing = false

Po drugie, dodać obserwatorów do powiadomień klawiatury systemowej:

// MARK: - Overriding ViewController Life Cycle Methods
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: .UIKeyboardWillChangeFrame, object: nil)
}

Po trzecie, należy przygotować funkcję animacji:

func adjustTableViewInsets(keyboardHeight: CGFloat, duration: NSNumber, curve: NSNumber){
    var extraHeight: CGFloat = 0
    if keyboardHeight > 0 {
        extraHeight = 20
        isKeyboardShowing = true
    } else {
        isKeyboardShowing = false
    }

    let contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight + extraHeight, right: 0)
    func animateFunc() {
        //refresh constraints
        //self.view.layoutSubviews()
        tableView.contentInset = contentInset
    }

    UIView.animate(withDuration: TimeInterval(duration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(curve))], animations: animateFunc, completion: nil)
}

Następnie dodać metody target / działania (nazywane przez obserwatorów):

// MARK: - Target/Selector Actions
func keyboardWillShow(notification: NSNotification) {
    if !isKeyboardShowing {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardHeight = keyboardSize.height

            let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
            let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber

            adjustTableViewInsets(keyboardHeight: keyboardHeight, duration: duration, curve: curve)
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
    let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
    adjustTableViewInsets(keyboardHeight: 0, duration: duration, curve: curve)
}

func keyboardWillChangeFrame(notification: NSNotification) {
    if isKeyboardShowing {
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber

        if let newKeyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardHeight = newKeyboardSize.height
            adjustTableViewInsets(keyboardHeight: keyboardHeight, duration: duration, curve: curve)
        }
    }
}

Wreszcie, nie zapomnij usunąć obserwatorów deinit lub w viewWillDisappear:

deinit {
    NotificationCenter.default.removeObserver(self)
}
Odpowiedział 10/06/2018 o 15:48
źródło użytkownik

głosy
0

Nie potrzeba żadnych obliczeń, skorzystaj z poniższego kodu będzie pracować: Ten kod użyłem w moim Dostosowane UITableViewCell, że to działa:

override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)}


func keyboardWillShow(_ notification:Notification) {

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
    tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
}}


func keyboardWillHide(_ notification:Notification) {

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
    tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
}}
Odpowiedział 22/02/2018 o 07:47
źródło użytkownik

głosy
0

Szybka 4 kompletne rozwiązania

  • Prawidłowo działa ze zmianami ramy klawiaturze (np wysokość klawiatury zmienia jak emojii → normalnej klawiaturze).
  • Umieszczenie zakładek i ToolBar wsparcie na przykład UITableView (w innych przykładach niepoprawne wypustki).
  • Dynamiczna animacja Czas trwania (nie zakodowane).
  • Protokół zorientowanych, więc łatwo można go używać w każdej sytuacji.
  • Spiralne wypustki działa zbyt.

Pisałem protokół pomocnika (można go pobrać jako GIST , ponieważ jest zbyt duża, aby odpowiedzieć na StackOverflow), więc twoim zdaniem wystarczy:

  1. Przyjąć KeyboardChangeFrameObserverprotokół:

    func willChangeKeyboardFrame(height: CGFloat, animationDuration: TimeInterval, animationOptions: UIViewAnimationOptions)
    
  2. Zadzwoń observeKeyboardFrameChanges()na pojawiać.

Przykładów realizacji tego protokołu do Tableview:

class TestViewController: UITableViewController, KeyboardChangeFrameObserver {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        observeKeyboardFrameChanges()
    }

    func willChangeKeyboardFrame(height: CGFloat, animationDuration: TimeInterval, animationOptions: UIViewAnimationOptions) {
        var adjustedHeight = height

        if let tabBarHeight = self.tabBarController?.tabBar.frame.height {
            adjustedHeight -= tabBarHeight
        } else if let toolbarHeight = navigationController?.toolbar.frame.height, navigationController?.isToolbarHidden == false {
            adjustedHeight -= toolbarHeight
        }

        if adjustedHeight < 0 { adjustedHeight = 0 }

        UIView.animate(withDuration: animationDuration, animations: {
            let newInsets = UIEdgeInsets(top: 0, left: 0, bottom: adjustedHeight, right: 0)
            self.tableView.contentInset = newInsets
            self.tableView.scrollIndicatorInsets = newInsets
        })
    }

}
Odpowiedział 12/01/2018 o 00:10
źródło użytkownik

głosy
0
// scroll tableview so content ends at the middle of the tableview (out of the way of the keyboard)
CGPoint newContentOffset = CGPointMake(0, [self.tableView contentSize].height - (self.tableView.bounds.size.height / 2));
[self.tableView setContentOffset:newContentOffset animated:YES];
Odpowiedział 27/06/2017 o 21:12
źródło użytkownik

głosy
0

Spójrz na moją wersję :)

    - (void)keyboardWasShown:(NSNotification *)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = cellSelected.superview.frame;
    bkgndRect.size.height += kbSize.height;
    [cellSelected.superview setFrame:bkgndRect];
    [tableView setContentOffset:CGPointMake(0.0, cellSelected.frame.origin.y-kbSize.height) animated:YES];
}


- (void)keyboardWasHidden:(NSNotification *)aNotification
{
    [tableView setContentOffset:CGPointMake(0.0, 0.0) animated:YES];
}
Odpowiedział 02/07/2016 o 20:32
źródło użytkownik

głosy
0

Oto moje rozwiązanie inspirowane ekranie „Edytuj wydarzenie” z iOS7 kalendarza aplikacji.

Jednym z najważniejszych punktów tego rozwiązania jest to, że klawiatura została zwolniona, gdy użytkownik przewinie tabeli.

Realizacja:

1) Dodaj właściwość, która będzie przechowywać wybrane pole tekstowe:

@property (strong) UITextField *currentTextField;

i zmienna BOOL że będziemy używać, aby sprawdzić, czy musimy ukryć klawiatury, gdy użytkownik przewija stołowego.

BOOL hideKeyboardOnScroll;

2) uchwyt UITextField zwrotnych Delegat:

#pragma mark - UITextFieldDelegate

- (void) textFieldDidBeginEditing: (UITextField *) textField {
    self.currentTextField = textField;
}

- (void) textFieldDidEndEditing: (UITextField *) textField {
    self.currentTextField = nil;
}

- (BOOL) textFieldShouldReturn: (UITextField *) textField {
   [textField resignFirstResponder];

    CGPoint newContentOffset = CGPointZero;
    if (tableView.contentSize.height > tableView.frame.size.height) {
        newContentOffset.y = MIN(tableView.contentOffset.y, tableView.contentSize.height - tableView.frame.size.height);
    }
    [tableView setContentOffset: newContentOffset animated: YES];

    return YES;
}

3) Stosować metodę UIScrollViewDelegate celu sprawdzenia tej tezy przewijania użytkownika.

#pragma mark - UIScrollViewDelegate

- (void) scrollViewDidScroll: (UIScrollView *) scrollView {
    if (hideKeyboardOnScroll == YES) {
        [self.currentTextField resignFirstResponder];
    }
}

4) otrzymywać powiadomienia w klawiaturze [viewWillAppear] Metoda viewcontroller i zrezygnować z [viewWillDisappear] metody.

- (void) viewWillAppear: (BOOL) animated {
    [super viewWillAppear: animated];

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

- (void) viewWillDisappear: (BOOL) animated {
    [super viewWillDisappear: animated];

    [ [NSNotificationCenter defaultCenter] removeObserver: self name: UIKeyboardDidShowNotification object: nil];
    [ [NSNotificationCenter defaultCenter] removeObserver: self name: UIKeyboardWillHideNotification object: nil];    
}

5) Uchwyt powiadomienia klawiszowych:

- (void) keyboardWillShow: (NSNotification *) notification {
    CGRect keyboardFrame = [ [ [notification userInfo] objectForKey: UIKeyboardFrameBeginUserInfoKey] CGRectValue];

    // Find cell with textfield.
    CGRect textFieldFrame = [tableView convertRect: self.currentTextField.frame fromView: self.currentTextField];
    NSIndexPath *indexPath = [tableView indexPathForRowAtPoint: textFieldFrame.origin];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
    //

    // Shrink tableView size.
    CGRect tableViewFrame = tableView.frame;
    tableView.frame = CGRectMake(tableView.frame.origin.x, tableView.frame.origin.y, tableView.frame.size.width,
                             self.view.frame.size.height - tableView.frame.origin.y - keyboardFrame.size.height);
    //

    // Check if cell is visible in shrinked table size.
    BOOL cellIsFullyVisible = YES;
    if ( cell.frame.origin.y < tableView.contentOffset.y ||
        (cell.frame.origin.y + cell.frame.size.height) > (tableView.contentOffset.y + tableView.frame.size.height) ) {
        cellIsFullyVisible = NO;
    }
    //

    // If cell is not fully visible when scroll table to show cell;
    if (cellIsFullyVisible == NO) {
        CGPoint contentOffset = CGPointMake(tableView.contentOffset.x, CGRectGetMaxY(cell.frame) - tableView.frame.size.height);
        if (cell.frame.origin.y < tableView.contentOffset.y) {
            contentOffset.y = cell.frame.origin.y;
        }
        contentOffset.y = MAX(0, contentOffset.y);

        // For some reason [setContentOffset] is called without delay then
        // this code may not work for some cells. That why we call it with brief delay.
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [UIView animateWithDuration: 0.5 animations:^{
                [tableView setContentOffset: contentOffset animated: NO];
            } completion: ^(BOOL finished) {
                hideKeyboardOnScroll = YES;
            }];
        });
    } else {
        hideKeyboardOnScroll = YES;
    }
    //

    // Finally restore original table frame.
    tableView.frame = tableViewFrame;
    //
}

- (void) keyboardWillHide: (NSNotification *) notification {
    [super keyboardWillHide: notification];

    hideKeyboardOnScroll = NO;
}
Odpowiedział 21/08/2014 o 15:43
źródło użytkownik

głosy
0

Myślę, że najlepszym sposobem jest poprzez UITableViewController.

Jeśli chcesz UITableView w UIViewController , po prostu zrobić contentView z osadzonym UITableViewController i umieścić następujące wiersze w viedDidLoad z UIViewController:

self.tableView = ((UITableViewController*)self.childViewControllers[0]).tableView;
self.tableView.delegate = self;
self.tableView.dataSource = self;

Łatwo ;)

Odpowiedział 06/06/2014 o 16:29
źródło użytkownik

głosy
0

Myślę, że nie ma „prawo” sposób to zrobić. Musisz wybrać najlepsze dopasowanie rozwiązania dla przypadku użycia. W moim iPad App Mam UIViewControllerktóry jest przedstawiony jako modalne UIModalPresentationFormSheeti składa się z części UITableView. Tabela ta zawiera dwa UITextFieldsna komórkę. Po prostu wywołanie scrollToRowAtIndexPath:atScrollPosition:animated:w textFieldDidBeginEditing:sposób nie działa na mnie. Dlatego stworzyliśmy tableFooterView:

- (void)viewDidLoad
{
    [super viewDidLoad];

    m_footerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, m_tableView.frame.size.width, 300.0f)];
    [m_footerView setBackgroundColor:[UIColor clearColor]];
    [m_tableView setTableFooterView:m_footerView];
    [m_footerView release];
}

Chodzi o to, że klawiatura ukrywa tableFooterViewi nie UITextFields. Więc tableFooterViewmusi być wystarczająco wysoka. Po tym można użyć scrollToRowAtIndexPath:atScrollPosition:animated:w textFieldDidBeginEditing:metodzie.

Myślę, że jest to również możliwe, aby pokazać i ukryć tableFooterViewdynamicznie dodając obserwatorów do powiadomień klawiaturą, ale nie próbowałem tego jeszcze:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

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

- (void)keyboardWillShow:(NSNotification *)notification 
{
     [m_tableView setTableFooterView:m_footerView];
}

- (void)keyboardWillHide:(NSNotification *)notification 
{
     [m_tableView setTableFooterView:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
Odpowiedział 15/09/2012 o 08:51
źródło użytkownik

głosy
0

Zrobiłem stworzyć mały projekt, który rozwiązuje ten problem z klawiaturą, w moim przypadku wystarczy, aby widok tabeli przejść się, gdy pojawia się klawiatura.

Mam nadzieję że to pomoże!

http://git.io/BrH9eQ

Odpowiedział 19/11/2011 o 21:21
źródło użytkownik

głosy
0

Ja po prostu spojrzał ponownie na iOS 5.0 lib odniesienia i znaleźć ten rozdział zatytułowany „Przenoszenie zawartości, która znajduje się pod klawiaturą”: TextAndWebiPhoneOS KeyboardManagement

Czy ta nowa od iOS 5, być może? Nie czytałem do niego jeszcze jak jestem w środku czegoś innego, ale może inni wiedzą więcej i może mnie oświecić i innych tutaj.

Czy doc Jabłko zastępują co zostało omówione tutaj lub jest informacja tutaj nadal użyteczne dla użytkowników iOS 5 SDK?

Odpowiedział 26/10/2011 o 12:07
źródło użytkownik

głosy
0

UITableViewControllerPrzewijanie robi automatycznie, rzeczywiście. Różnica w porównaniu z użyciem UIViewControllerjest, że trzeba stworzyć NavBar-Buttonitems programowo za pomocą przycisków NavigationController, gdy za pomocą TableViewController.

Odpowiedział 20/03/2011 o 20:59
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more