Ho cercato molto per il codice che ridimensiona la vista tabella per consentire la visualizzazione e l'occultamento della tastiera, ma quasi ogni singolo post che ho trovato presuppone che la vista tabella stia prendendo l'intera vista della sua vista controller. Ho un'applicazione per iPad in cui la vista tabella sta prendendo solo parte dello schermo. Qual è il modo corretto per ridimensionare la vista tabella in questo caso? (Tutto il codice nei post che ho citato sopra non riesce)Algoritmo di ridimensionamento tastiera UITableView generico
risposta
Il seguente codice fa quello che vuoi e funziona con qualsiasi dispositivo e qualsiasi layout. Il codice è per gentile concessione dello Sensible TableView framework (con il permesso di copiare e utilizzare).
- (void)keyboardWillShow:(NSNotification *)aNotification
{
if(keyboardShown)
return;
keyboardShown = YES;
// Get the keyboard size
UIScrollView *tableView;
if([self.tableView.superview isKindOfClass:[UIScrollView class]])
tableView = (UIScrollView *)self.tableView.superview;
else
tableView = self.tableView;
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [tableView.superview convertRect:[aValue CGRectValue] fromView:nil];
// Get the keyboard's animation details
NSTimeInterval animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
UIViewAnimationCurve animationCurve;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
// Determine how much overlap exists between tableView and the keyboard
CGRect tableFrame = tableView.frame;
CGFloat tableLowerYCoord = tableFrame.origin.y + tableFrame.size.height;
keyboardOverlap = tableLowerYCoord - keyboardRect.origin.y;
if(self.inputAccessoryView && keyboardOverlap>0)
{
CGFloat accessoryHeight = self.inputAccessoryView.frame.size.height;
keyboardOverlap -= accessoryHeight;
tableView.contentInset = UIEdgeInsetsMake(0, 0, accessoryHeight, 0);
tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, accessoryHeight, 0);
}
if(keyboardOverlap < 0)
keyboardOverlap = 0;
if(keyboardOverlap != 0)
{
tableFrame.size.height -= keyboardOverlap;
NSTimeInterval delay = 0;
if(keyboardRect.size.height)
{
delay = (1 - keyboardOverlap/keyboardRect.size.height)*animationDuration;
animationDuration = animationDuration * keyboardOverlap/keyboardRect.size.height;
}
[UIView animateWithDuration:animationDuration delay:delay
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{ tableView.frame = tableFrame; }
completion:^(BOOL finished){ [self tableAnimationEnded:nil finished:nil contextInfo:nil]; }];
}
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
if(!keyboardShown)
return;
keyboardShown = NO;
UIScrollView *tableView;
if([self.tableView.superview isKindOfClass:[UIScrollView class]])
tableView = (UIScrollView *)self.tableView.superview;
else
tableView = self.tableView;
if(self.inputAccessoryView)
{
tableView.contentInset = UIEdgeInsetsZero;
tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
if(keyboardOverlap == 0)
return;
// Get the size & animation details of the keyboard
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [tableView.superview convertRect:[aValue CGRectValue] fromView:nil];
NSTimeInterval animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
UIViewAnimationCurve animationCurve;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
CGRect tableFrame = tableView.frame;
tableFrame.size.height += keyboardOverlap;
if(keyboardRect.size.height)
animationDuration = animationDuration * keyboardOverlap/keyboardRect.size.height;
[UIView animateWithDuration:animationDuration delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{ tableView.frame = tableFrame; }
completion:nil];
}
- (void) tableAnimationEnded:(NSString*)animationID finished:(NSNumber *)finished contextInfo:(void *)context
{
// Scroll to the active cell
if(self.activeCellIndexPath)
{
[self.tableView scrollToRowAtIndexPath:self.activeCellIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
[self.tableView selectRowAtIndexPath:self.activeCellIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
Note:
a. I due metodi sopra riportati sono stati aggiunti al centro di notifica utilizzando il seguente codice:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
b. Gli ivar usati sopra sono stati dichiarati in questo modo:
BOOL keyboardShown;
CGFloat keyboardOverlap;
c. 'self.activeCellIndexPath' è sempre impostato su indexPath della cella proprietaria del UITextField/UITextView attualmente attivo.
Divertiti! :)
Questo è fantastico! funziona come un fascino, grazie mille! – Matt
Vorrei aggiungere solo un'aggiunta. Se l'altezza di UITableViewCell può essere maggiore della dimensione rimasta per presentare UITableView, è meglio modificare il metodo tableAnimationEnded in modo che scorra su "TOP" anziché "NONE". Inoltre, se si presenta la tastiera alla selezione di una cella e si è già gestita la selezione di UITableView, non è necessario selezionare nuovamente "activeCellIndexPath". – Lubakis
Check out this project, è trascinare e rilasciare quindi basta dichiarare il tablview come tipo TPKeyboardAvoidingTableView
Soluzione semplice - registrarsi per ricevere le notifiche della tastiera su init o viewDidLoad con:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
poi quando si riceve la notifica, è possibile utilizzare la data rect della tastiera per regolare la struttura del vostro tableView:
- (void)keyboardWillShow:(NSNotification *)notification
{
// Get the size of the keyboard.
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect newTableFrame = _myTableView.frame;
//Here make adjustments to the tableview frame based on the value in keyboard size
...
_myTableView.frame = newTableFrame;
}
- (void)keyboardWillHide:(NSNotification *)notification
{
//Here change the table frame back to what it originally was.
}
Vorrei suggerire di registrarsi in viewWillAppear: e annullare la registrazione in viewWillDisappear: (a causa di osservatore del centro di notifica che mantiene e perché viewDidUnload: (per annullare la registrazione) è deprecato da iOS 6) – JakubKnejzlik
ho trovato la soluzione più semplice per essere questa (io non sono fan di utilizzare subviews per questo genere di cose):
registro per la tastiera cambiamento telaio notifica (idealmente registrarsi in viewWillAppear: e annullare la registrazione in viewWillDisappear :):
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
e poi nel metodo:
- (void)keyboardDidChangeFrame:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect kbIntersectFrame = [window convertRect:CGRectIntersection(window.frame, kbFrame) toView:self.scrollView];
kbIntersectFrame = CGRectIntersection(self.bounds, kbIntersectFrame);
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbIntersectFrame.size.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
o se si vuole sbarazzarsi del "salto" dopo aver cambiato contentInset:
- (void)keyboardDidChangeFrame:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect kbIntersectFrame = [window convertRect:CGRectIntersection(window.frame, kbFrame) toView:self.scrollView];
kbIntersectFrame = CGRectIntersection(self.scrollView.bounds, kbIntersectFrame);
// get point before contentInset change
CGPoint pointBefore = self.scrollView.contentOffset;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbIntersectFrame.size.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// get point after contentInset change
CGPoint pointAfter = self.scrollView.contentOffset;
// avoid jump by settings contentOffset
self.scrollView.contentOffset = pointBefore;
// and now animate smoothly
[self.scrollView setContentOffset:pointAfter animated:YES];
}
Funziona molto bene ed è più semplice di quello di Tarek sopra. Non scrivo usando la UIWindow, ma dovrebbe essere facilmente passato alla vista, no? – Brian
Sì, in teoria. Tieni a mente che le coordinate della tastiera sono in "dimensioni della finestra", quindi se la vista non ha la stessa dimensione/posizione della finestra, non potrebbe funzionare correttamente. – JakubKnejzlik
La soluzione più semplice è quella di aggiungere la mia estensione UIViewController+Keyboard.swift
al progetto, con una singola linea setupKeyboardNotifcationListenerForScrollView(tableView)
sarà ridimensionamento automatico automaticamente. Non c'è bisogno di sottoclasse nulla, solo un'estensione!La sua open source a SingleLineKeyboardResize
Ecco il metodo di tastiera:
func keyboardControl(notification: NSNotification, isShowing: Bool) {
var userInfo = notification.userInfo!
let keyboardRect = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue
let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey]!.unsignedIntValue
let convertedFrame = self.view.convertRect(keyboardRect, fromView: nil)
let heightOffset = self.view.bounds.size.height - convertedFrame.origin.y
let options = UIViewAnimationOptions(rawValue: UInt(curve) << 16)
let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]!.doubleValue
//your UITableView bottom constrant
self.tableViewMarginBottomConstraint.constant = heightOffset
var contentInsets = UIEdgeInsetsZero
if isShowing {
contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardRect.size.height), 0.0)
}
UIView.animateWithDuration(
duration,
delay: 0,
options: options.union(.LayoutSubviews).union(.BeginFromCurrentState),
animations: {
self.listTableView.contentInset = contentInsets
self.listTableView.scrollIndicatorInsets = contentInsets
self.listTableView.scrollBottomToLastRow()
self.view.layoutIfNeeded()
},
completion: { bool in
})
}
Qui è l'estensione UITableView:
extension UITableView {
func totalRows() -> Int {
var i = 0
var rowCount = 0
while i < self.numberOfSections {
rowCount += self.numberOfRowsInSection(i)
i++
}
return rowCount
}
var lastIndexPath: NSIndexPath {
get { return NSIndexPath(forRow: self.totalRows()-1, inSection: 0) }
}
func scrollBottomToLastRow() {
self.scrollToRowAtIndexPath(self.lastIndexPath, atScrollPosition: .Bottom, animated: false)
}
}
si può ottenere quello che stai cercando utilizzando IQKeyboardManager, è un libreria codeless, devi solo aggiungerla al tuo Podfile: pod 'IQKeyboardManager' e il gioco è fatto, passerà l'effetto di scorrimento quando viene mostrata la tastiera anche se UITextField/UITextView non fa parte di scrollView/tableView.
- 1. UITableView tableFooterView ridimensionamento strano
- 2. viewport di ridimensionamento tastiera mobile
- 3. Animazione ridimensionamento layout con tastiera aperta
- 4. PIL: ridimensionamento Image: algoritmo simile a Firefox di
- 5. Ridimensionamento dell'immagine o algoritmo di duplicazione DOM in JavaScript?
- 6. Impedisci il ridimensionamento del documento/ridimensionamento del browser quando si apre la tastiera di Android
- 7. Webview non ridimensionamento quando viene visualizzata la tastiera
- 8. iOS: Disabilita l'animazione UITableView quando viene visualizzata la tastiera
- 9. Ridimensionamento/ridimensionamento del grafico di Google sul ridimensionamento della finestra
- 10. Java - Ho bisogno di un algoritmo di ridimensionamento delle immagini molto veloce
- 11. Admob annunci non compaiono nel piè di pagina di UITableView quando la tastiera è mostrato
- 12. Valore di campo generico di riflessione generico
- 13. Comprendere un algoritmo di ridimensionamento della mappa per il calcolo della sovrapposizione
- 14. jQuery UI ridimensionabile finestra di ridimensionamento evento di ridimensionamento
- 15. Algoritmo di riduzione della coda?
- 16. Traduci tastiera da tastiera a combinazione tastiera
- 17. Ridimensionamento di una bitmap
- 18. Ridimensionamento di ElasticSearch
- 19. Segnale di ridimensionamento QWidget?
- 20. Java2D: problemi di ridimensionamento
- 21. Ridimensionamento di LibGDX FrameBuffer
- 22. Ridimensionamento di un GLKView
- 23. Ridimensionamento di un array
- 24. Scorrimento di UITableView
- 25. Tastiera computer tastiera Telegram
- 26. Dimensionamento e ridimensionamento SKSpriteNode
- 27. Ridimensionamento dei controlli con ridimensionamento modulo
- 28. Ridimensionamento FlexSlider 2 al ridimensionamento della finestra
- 29. Prevenzione del ridimensionamento del viewport della pagina Web quando è attiva la tastiera virtuale Android
- 30. Tastiera iPhone personalizzata
Non hai menzionato alcun codice che non riesce. – Mundi
Perché non regolare il codice che hai trovato per tenere conto della differenza tra la parte inferiore del riquadro di visualizzazione tabella e il riquadro di visualizzazione completa? – Anton