Po wielu próbach i błędach poddaję się i zadaję pytanie. Widziałem wiele osób z podobnymi problemami, ale nie mogę uzyskać wszystkich odpowiedzi.
Mam taki, UITableView
który składa się z niestandardowych komórek. Komórki składają się z 5 pól tekstowych obok siebie (coś w rodzaju siatki).
Kiedy próbuję przewijać i edytować komórki u dołu UITableView
, nie mogę prawidłowo ustawić komórek nad klawiaturą.
Widziałem wiele odpowiedzi na temat zmiany rozmiarów widoków itp., Ale żadna z nich do tej pory nie działała dobrze.
Czy ktoś mógłby wyjaśnić „właściwy” sposób na zrobienie tego na konkretnym przykładzie z kodem?
Odpowiedzi:
Jeśli użyjesz UITableViewController zamiast UIViewController, zrobi to automatycznie.
źródło
Funkcja przewijania może być znacznie prostsza:
Otóż to. Żadnych obliczeń.
źródło
contentInset
, który najwyraźniej nie jest brany pod uwagę przy pytaniu ovisibleRows
lubindexPathsForVisibleRows
.Robię coś bardzo podobnego, to jest ogólne, nie ma potrzeby obliczania czegoś konkretnego dla twojego kodu. Sprawdź uwagi w kodzie:
W MyUIViewController.h
W MyUIViewController.m
Wersja Swift 1.2+:
źródło
[tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionMiddle animated: YES];
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate]; CGFloat tabBarHeight = appDelegate.tabBarController.tabBar.frame.size.height;
Następnie odejmij tabBarHeight od wysokości klawiatury, gdziekolwiek używasz wysokości klawiatury.Najprostsze rozwiązanie dla Swift 3 , oparte na rozwiązaniu Bartłomieja Semańczyka :
źródło
Notification
Zamiast tegoNSNotification
byłoby więcej „Swift 3-y” :-)Miałem ten sam problem, ale zauważyłem, że pojawia się tylko w jednym widoku. Zacząłem więc szukać różnic w kontrolerach.
Dowiedziałem się, że zachowanie przewijania jest ustawione w
- (void)viewWillAppear:(BOOL)animated
super wystąpieniu.Dlatego pamiętaj o wdrożeniu w ten sposób:
I nie ma znaczenia, czy używasz
UIViewController
lubUITableViewController
; sprawdziłem to, umieszczającUITableView
jako subview self.view wUIViewController
. To było to samo zachowanie. Widok nie pozwalał na przewijanie, jeśli[super viewWillAppear:animated];
brakowało połączenia .źródło
mogłem to przegapić, ponieważ nie przeczytałem tutaj całego postu, ale to, co wymyśliłem, wydaje się zwodniczo proste. nie przeszedłem tego przez pisarza, testując we wszystkich sytuacjach, ale wygląda na to, że powinno działać dobrze.
po prostu dostosuj contentInset widoku tabeli o wysokość klawiatury, a następnie przewiń komórkę do dołu:
i oczywiście
czy to jest zbyt proste? czy coś mi brakuje? jak dotąd działa dla mnie dobrze, ale jak powiedziałem, nie przełożyłem tego przez pisarza ...
źródło
[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
contentInset
i gwałtownie zmieniać granic przewijania.Myślę, że opracowałem rozwiązanie pasujące do zachowania aplikacji Apple.
Po pierwsze, w twoim widokuWillAppear: subskrybuj powiadomienia z klawiatury, abyś wiedział, kiedy klawiatura pokaże się i ukryje, a system powie ci rozmiar klawiatury, ale nie zapomnij wyrejestrować się z widokuWillDisappear :.
Zaimplementuj metody podobne do poniższych, aby dostosować rozmiar tabeliView, aby dopasować widoczny obszar po wyświetleniu klawiatury. Tutaj osobno śledzę stan klawiatury, więc mogę wybrać, kiedy sam ustawić tableView z powrotem na pełną wysokość, ponieważ otrzymujesz te powiadomienia przy każdej zmianie pola. Nie zapomnij wdrożyć keyboardWillHide: i wybierz odpowiednie miejsce, aby naprawić rozmiar tableView.
Oto bit przewijania, najpierw obliczamy kilka rozmiarów, a następnie widzimy, gdzie jesteśmy w widocznym obszarze, i ustawiamy prostokąt, który chcemy przewinąć, aby był albo widokiem połowy powyżej, albo poniżej środka pola tekstowego gdzie jest to w widoku. W tym przypadku mamy tablicę pól UITextField i wyliczenie, które je śledzi, więc pomnożenie rowHeight przez numer wiersza daje nam rzeczywiste przesunięcie ramki w tym zewnętrznym widoku.
To wydaje się działać całkiem nieźle.
źródło
UIKeyboardBoundsUserInfoKey
jest przestarzałe od iOS 3.2. Zobacz moje rozwiązanie poniżej, które działa we wszystkich aktualnych wersjach iOS ≥ 3.0. / @ iPhoneDevJeśli możesz użyć
UITableViewController
, otrzymasz tę funkcję za darmo. Czasami jednak nie jest to opcja, szczególnie jeśli potrzebujesz wielu widoków, nie tylkoUITableView
.Niektóre przedstawione tutaj rozwiązania nie działają na iOS ≥4, niektóre nie działają na iPadzie lub w trybie poziomym, niektóre nie działają na klawiaturach Bluetooth (gdzie nie chcemy przewijania), niektóre nie działa podczas przełączania między wieloma polami tekstowymi. Jeśli więc wybierzesz jakieś rozwiązanie, sprawdź te przypadki. To rozwiązanie, którego
używamy,używane w InAppSettingsKit :Oto pełny kod klasy w InAppSettingsKit. Aby to przetestować, użyj okienka podrzędnego „Pełna lista”, w którym możesz przetestować wyżej wymienione scenariusze.
źródło
Najprostsze rozwiązanie dla Swift :
źródło
Mam nadzieję, że macie już rozwiązanie, czytając je wszystkie. Ale moje rozwiązanie znalazłem w następujący sposób. Oczekuję, że masz już komórkę
UITextField
. Więc przygotowując, po prostu trzymaj indeks wiersza w znaczniku pola tekstowego.Utwórz
activeTextField
instancję oUITextField
zasięgu globalnym, jak poniżej:Więc teraz po prostu skopiuj wklej mój kod na końcu. I również nie zapomnij dodać
UITextFieldDelegate
Rejestruje klawiaturę
notifications
Uchwyty Klawiatura
Notifications
:Wywoływany, gdy wiadomość
UIKeyboardDidShowNotification
jest wysyłana.Wywoływany, gdy wiadomość
UIKeyboardWillHideNotification
jest wysyłanaTeraz pozostaje jedna rzecz: Wywołaj
registerForKeyboardNotifications
metodę doViewDidLoad
metody w następujący sposób:Gotowe, masz nadzieję, że twoja
textFields
wola nie będzie już ukryta przez klawiaturę.źródło
Łącząc i wypełniając puste pola z kilku odpowiedzi (w szczególności Ortwin Gentz, użytkownik 98013) i innego postu, to zadziała po wyjęciu z pudełka dla SDK 4.3 na iPadzie w trybie pionowym lub poziomym:
źródło
Jeśli używasz uitableview do umieszczania pól tekstowych ( od Jeffa Lamarche ), możesz po prostu przewinąć widok tabeli przy użyciu metody delegowania.
(Uwaga: moje pola tekstowe są przechowywane w tablicy o tym samym indeksie, co tam wiersz w widoku tabeli)
źródło
Powiadomienia z klawiatury działają, ale przykładowy kod Apple zakłada, że widok przewijania jest widokiem głównym okna. Zazwyczaj tak nie jest. Musisz skompensować paski tabulatorów itp., Aby uzyskać właściwe przesunięcie.
To łatwiejsze niż się wydaje. Oto kod, którego używam w UITableViewController. Ma dwie zmienne instancji, hiddenRect i keyboardShown.
źródło
UIKeyboardCenterEndUserInfoKey
iUIKeyboardBoundsUserInfoKey
są przestarzałe od iOS 3.2. Zobacz moje rozwiązanie poniżej, które działa we wszystkich aktualnych wersjach iOS ≥ 3.0.Jeśli używasz
Three20
, użyjautoresizesForKeyboard
właściwości. Wystarczy ustawić-initWithNibName:bundle
metodę kontrolera widokuZajmuje się to:
Gotowe i gotowe.
źródło
Moje podejście:
Najpierw podklasę UITextField i dodaję właściwość indexPath. W komórce ... Metoda i przekazuję właściwość indexPath.
Następnie dodaję następujący kod:
do textFieldShould / WillBegin ... itp.
Kiedy klawiatura znika, musisz ją odwrócić za pomocą:
źródło
Bardziej płynne rozwiązanie. Wchodzi w metody delegowania UITextField, więc nie wymaga bałaganu z powiadomieniami UIKeyboard.
Uwagi dotyczące wdrożenia:
kSettingsRowHeight - wysokość UITableViewCell.
offsetTarget i offsetThreshold są wyłączone z kSettingsRowHeight. Jeśli używasz innej wysokości wiersza, ustaw te wartości na właściwość y punktu. [alt: oblicz przesunięcie wiersza w inny sposób.]
}
}
źródło
Użyj
UITextField's
delegate
metody:Szybki
Cel C
źródło
Kompletne rozwiązanie Swift 4.2
Stworzyłem GIST z zestawem protokołów, który upraszcza pracę dzięki dodawaniu dodatkowego miejsca, gdy klawiatura jest pokazywana, ukryta lub zmieniana.
Funkcje :
Stosowanie
Przykład użycia podstawowego w kontrolerze widoku zawierającym widok przewijania (widok tabeli jest oczywiście obsługiwany).
Rdzeń: obserwator zmienia ramkę
Protokół
KeyboardChangeFrameObserver
uruchamia zdarzenie po każdej zmianie ramki klawiatury (w tym pokazywaniu, ukrywaniu, zmianie ramki).addKeyboardFrameChangesObserver()
naviewWillAppear()
lub podobną metodę.removeKeyboardFrameChangesObserver()
naviewWillDisappear()
lub podobną metodę.Realizacja: przewijany widok
ModifableInsetsOnKeyboardFrameChanges
protokół dodajeUIScrollView
obsługę podstawowego protokołu. Zmienia on wypustki widoku przewijania po zmianie ramki klawiatury.Twoja klasa musi ustawić widok przewijania, wstawki będą zwiększane / zmniejszane przy zmianie ramki klawiatury.
źródło
Ponieważ masz pola tekstowe w tabeli, najlepszym sposobem jest zmiana rozmiaru tabeli - musisz ustawić tableView.frame na mniejszą wysokość o rozmiar klawiatury (myślę, że około 165 pikseli), a następnie rozwinąć go ponownie, gdy klawiatura jest zwolniona.
W tym momencie możesz opcjonalnie również wyłączyć interakcję użytkownika dla tableView, jeśli nie chcesz, aby użytkownik przewijał.
źródło
Działa to doskonale, a także na iPadzie.
źródło
Próbowałem prawie tego samego podejścia i wymyśliłem prostszy i mniejszy kod do tego samego. Utworzyłem IBOutlet iTextView i skojarzyłem go z UITextView w IB.
źródło
Więc po godzinach wyczerpującej pracy, próbując wykorzystać te obecne rozwiązania (i całkowicie zawiodłem) w końcu sprawiłem, że wszystko działało dobrze i zaktualizowałem je, aby używały nowych bloków animacji. Moja odpowiedź jest całkowicie oparta na powyższej odpowiedzi Ortwina .
Więc z jakiegokolwiek powodu powyższy kod po prostu nie działał dla mnie. Moja konfiguracja wydawała się dość podobna do innych, ale może dlatego, że byłem na iPadzie lub 4.3 ... nie mam pojęcia. Robił trochę zwariowanej matematyki i strzelał do mojego widoku z ekranu poza ekranem.
Zobacz końcowy wynik mojego rozwiązania: http://screencast.com/t/hjBCuRrPC (zignoruj zdjęcie. :-P)
Poszedłem więc do sedna tego, co robił Ortwin, ale zmieniłem sposób, w jaki robiło to matematykę, aby dodać pochodzenie. Y i rozmiar. Wysokość mojego widoku tabeli z wysokością klawiatury. Kiedy odejmuję wysokość okna od tego wyniku, mówi mi to, ile przecięć mam na sobie. Jeśli jego wartość jest większa niż 0 (aka występuje pewne nakładanie się), wykonuję animację wysokości klatki.
Ponadto wystąpiły pewne problemy z przerysowaniem, które zostały rozwiązane przez 1) Oczekiwanie na przewinięcie do komórki, aż animacja została zakończona i 2) przy użyciu opcji UIViewAnimationOptionBeginFromCurrentState podczas ukrywania klawiatury.
Kilka rzeczy do zapamiętania.
Znów nie zbliżyłbym się do tej odpowiedzi, gdybym nie dostarczył jej sedna. Oto kod:
źródło
To rozwiązanie działa dla mnie, PROSZĘ zwróć uwagę na linię
Możesz zmienić wartość 160, aby dopasować ją do siebie
źródło
Bardzo interesujący wątek do dyskusji, również napotkałem ten sam problem, może być gorszy, ponieważ
Przeczytaj więc tutaj wątki i wdrożyłem moją wersję, która pomogła mi w zwiększaniu zawartości w iPadzie w trybie poziomym . Oto kod (to nie jest głupi dowód i wszystko, ale naprawiło mój problem) Najpierw musisz mieć delegata w swojej niestandardowej klasie komórek, która po rozpoczęciu edycji wysyła pole tekstowe do twojego kontrolera widoku i ustawia pole activefield = pole tekstowe
// WYKONANE TYLKO DO OBSŁUGI TRYBU KRAJOBRAZU
// Wywoływany, gdy wysyłane jest UIKeyboardWillHideNotification
-anoop4real
źródło
Właśnie rozwiązałem taki problem po tym, jak poleciłem masę rozwiązań znalezionych przez Google i Stack Overflow.
Najpierw upewnij się, że skonfigurowałeś IBOutlet swojego UIScrollView, a następnie przyjrzyj się bliżej Apple Doc: Zarządzanie klawiaturą . Na koniec, jeśli możesz przewijać tło, ale klawiatura nadal pokrywa pola tekstowe, spójrz na ten fragment kodu:
Główna różnica między tym kawałkiem a Apple polega na warunku if. Uważam, że obliczenia odległości przewijania przez Apple i warunek, czy pole tekstowe pokryte klawiaturą nie są dokładne, więc zmodyfikowałem jak wyżej.
Daj znać czy działa
źródło
Przykład w Swift, używając dokładnego punktu pola tekstowego z Get indexPath z UITextField w UITableViewCell za pomocą Swift :
źródło
Kolejna łatwa metoda (działa tylko z jedną sekcją)
źródło
Jeśli Twoim UITableView zarządza podklasa UITableViewController, a nie UITableView, a delegatem pola tekstowego jest UITableViewController, powinien on automatycznie zarządzać całym przewijaniem - wszystkie inne komentarze są bardzo trudne do wdrożenia w praktyce.
Dobry przykład można znaleźć w przykładowym projekcie kodu Apple: TaggedLocations.
Możesz zobaczyć, że przewija się on automatycznie, ale wydaje się, że nie ma kodu, który to robi. Ten projekt ma również niestandardowe komórki widoku tabeli, więc jeśli zbudujesz aplikację z nim jako przewodnikiem, powinieneś uzyskać pożądany wynik.
źródło
Oto, w jaki sposób stworzyłem tę pracę, która jest mieszanką odpowiedzi Sama Ho i Marcela W oraz niektórych własnych poprawek błędów w moim gównianym kodzie. Korzystałem z UITableViewController. Tabela wyświetla się teraz poprawnie, gdy pokazana jest klawiatura.
1) W
viewDidLoad
dodałem:self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
2) Zapomniałem nazwać
super
ekwiwalentów wviewWillAppear
iawakeFromNib
. Dodałem je z powrotem.źródło
UITableViewController
rzeczywiście przewija automatycznie. Różnica w porównaniu do używania aUIViewController
polega na tym, że musisz programowo tworzyć przyciski Navbar-Buttonitems przy użyciuNavigationController
, podczas korzystania zTableViewController
.źródło