Обложки iPhone для iPhone UITextField
У меня есть приложение, где в Interface Builder я установил UIView
, у которого есть текстовое поле в нижней части представления. Когда я запускаю приложение и пытаюсь ввести текст в это поле, клавиатура сдвигает верхнюю часть поля, поэтому я не вижу, что я набираю, пока не скрою клавиатуру.
Кто-нибудь еще сталкивается с этой проблемой и нашел хороший способ ее решить, не делая прокрутки родительского представления или перемещая текстовое поле дальше экрана?
Ответы
Ответ 1
Обычное решение состоит в том, чтобы сместить поле (и все выше него) с анимацией, а затем вернуться, когда вы закончите. Возможно, вам нужно будет поместить текстовое поле и некоторые другие элементы в другое представление и сдвинуть представление как единое целое. (Я называю эти вещи "тарелки", как в "тектонических плитах", но это только я). Но вот общая идея, если вам не нужно проявлять фантазию.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
Ответ 2
Это сотворило для меня чудеса скользящие uitextfields
В частности, это полезно для вычисления расстояния анимации слайда в зависимости от положения текстового поля.
Ответ 3
IQKeyboardManager сделайте это для вас с НЕТ ЛИНИИ КОДА, нужно только перетащить связанный источник файл для проекта. IQKeyboardManager также поддерживают Ориентация устройства, Автоматическое управление UIToolbar, keyboardDistanceFromTextField и намного больше, чем вы думаете.
![enter image description here]()
Вот диаграмма потока управления:
![Control Flow Chart]()
Шаг 1: - Добавлены глобальные уведомления UITextField
, UITextView
и UIKeyboard
в одноэлементном классе. Я назвал его IQKeyboardManager.
Шаг 2: - Если найдено UIKeyboardWillShowNotification
, UITextFieldTextDidBeginEditingNotification
или UITextViewTextDidBeginEditingNotification
уведомлений, попробуйте получить экземпляр topMostViewController
из иерархии UIWindow.rootViewController
. Чтобы правильно раскрыть UITextField
/UITextView
на нем, нужно отрегулировать кадр topMostViewController.view
.
Шаг 3: - Расчетное ожидаемое расстояние перемещения topMostViewController.view
по отношению к первому ответу UITextField
/UITextView
.
Шаг 4: - Перемещено topMostViewController.view.frame
вверх/вниз в соответствии с ожидаемым расстоянием перемещения.
Шаг 5: - Если найдено UIKeyboardWillHideNotification
, UITextFieldTextDidEndEditingNotification
или UITextViewTextDidEndEditingNotification
уведомление, затем попробуйте получить экземпляр topMostViewController
из иерархии UIWindow.rootViewController
.
Шаг 6: - Рассчитанное нарушенное расстояние topMostViewController.view
, которое необходимо восстановить в исходное положение.
Шаг7: - Восстановлено topMostViewController.view.frame
вниз в соответствии с нарушенным расстоянием.
Шаг 8: - Инициированный singleton IQKeyboardManager экземпляр класса при загрузке приложения, поэтому каждый UITextField
/UITextView
в приложении будет автоматически изменяться в соответствии с ожидаемым расстоянием перемещения.
Что все
Ответ 4
У меня такая же проблема в ячейках textField UITableView
. Я решаю эту проблему, применяя следующий метод для прослушивания уведомления о клавиатуре.
Наблюдатель для уведомлений здесь:
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
Отправляйте эти уведомления, используя следующую функцию:
(void)keyboardWasShown:(NSNotification*)aNotification
(void)keyboardWillBeHidden:(NSNotification*)aNotification
Ответ 5
Чтобы расширить ответ от Amagrammer, вот пример класса:
LoginViewController.h
@interface LoginViewController : UIViewController <UITextFieldDelegate> {
}
@property (nonatomic, retain) IBOutlet UITextField *emailTextField;
@property (nonatomic, retain) IBOutlet UITextField *passwordTextField;
Обратите внимание, что мы реализуем "UITextFieldDelegate"
LoginViewController.m
@implementation LoginViewController
@synthesize emailTextField=_emailTextField;
@synthesize passwordTextField=_passwordTextField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Register to receive an update when the app goes into the backround
//It will call our "appEnteredBackground method
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appEnteredBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
}
return self;
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
//This is called when the app goes into the background.
//We must reset the responder because animations will not be saved
- (void)appEnteredBackground{
[self.emailTextField resignFirstResponder];
[self.passwordTextField resignFirstResponder];
}
Ответ 6
Как насчет официального решения: Перемещение содержимого, находящегося под клавиатурой
Настройка вашего контента обычно включает временное изменение размера больше просмотров и размещения их так, чтобы текстовый объект оставался видимый. Самый простой способ управления текстовыми объектами с помощью клавиатуры - встроить их в объект UIScrollView (или один из его подклассов как UITableView). Когда клавиатура отображается, все, что вам нужно сделать reset область содержимого прокрутки и прокрутка требуемого текстовый объект в позицию. Таким образом, в ответ на UIKeyboardDidShowNotification, ваш метод обработчика будет выполнять следующее:
- Получить размер клавиатуры.
- Отрегулируйте нижнюю вставку содержимого вашего вида прокрутки на клавиатуре высота.
- Прокрутите целевое текстовое поле в виде.
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (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);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
Ответ 7
Проверьте это.
Никаких хлопот для вас.
Это решение очень аккуратно. Все, что вам нужно сделать, это добавить ваши текстовые поля в UIScrollView
и изменить его класс на TPKeyboardAvoidingScollView
, если вы используете раскадровки. Вид прокрутки расширяется таким образом, что он будет обнаруживать, когда клавиатура видна и будет двигаться над клавиатурой на разумном расстоянии. Это идеальное решение, потому что оно не зависит от вашего UIViewController
. Все необходимые вещи выполняются в рамках вышеупомянутого класса. Спасибо Майкл Тайсон и все.
TPKeyboardAvoiding
Ответ 8
Ниже приведена быстрая версия ответа Amagrammer. Кроме того, вариант с использованием события UIKeyboardWillShowNotification, так как мне нужно было знать размер клавиатуры, прежде чем перемещать представление в сторону.
var keyboardHeight:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChange:", name: UIKeyboardWillShowNotification, object: nil)
}
func textFieldDidBeginEditing(textField: UITextField) {
//keyboardWillChange (below) is used instead of textFieldDidBeginEditing because textFieldDidBeginEditing
//is called before the UIKeyboardWillShowNotification necessary to determine the keyboard height.
}
func textFieldDidEndEditing(textField: UITextField) {
animateTextField(false)
}
func animateTextField(textFieldUp:Bool) {
let movementDistance:CGFloat = keyboardHeight
let movementDuration = 0.3
let movement:CGFloat = (textFieldUp ? -movementDistance : movementDistance)
UIView.beginAnimations("anim", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
func keyboardWillChange(notification:NSNotification) {
let keyboardRect:CGRect = ((notification.userInfo![UIKeyboardFrameEndUserInfoKey])?.CGRectValue)!
keyboardHeight = keyboardRect.height
animateTextField(true)
}
Ответ 9
В (ссылка сейчас мертва, здесь ссылка Wayback: https://web.archive.org/web/20091123074029/http://acts-as-geek.blogspot.com/2009/11/editing-textfields-without-obscuring.html). Он показывает, как переместить существующий UIView
на UIScrollView
и прокручивать его автоматически при появлении клавиатуры.
Я немного обновил его, чтобы вычислить правильную высоту для UIScrollView
, когда есть элементы управления (например, UITabBar
) ниже UIScrollBar
. См. опубликовать обновление uiview.
Ответ 10
Здесь решение с использованием Xcode5, iOS7:
Используйте блоки UITextfieldDelegate и анимации.
Это почти весь код для ViewController, но я хотел включить код делегата для тех, кто еще несколько не знаком с шаблоном делегата (например, я). Я также включил код, чтобы скрыть клавиатуру, когда вы касаетесь текста.
Вы можете перемещать представления (кнопки, текстовые поля и т.д.) настолько высоко, насколько вам хотелось бы просто поместить их на место (+100, а затем - 100).
@interface ViewController () <UITextFieldDelegate>
@property (strong, nonatomic) IBOutlet UITextField *MyTextField;
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.MyTextField.delegate = self;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(@"text began editing");
CGPoint MyPoint = self.MyTextField.center;
[UIView animateWithDuration:0.3
animations:^{
self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y - 100);
}];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(@"text ENDED editing");
CGPoint MyPoint = self.MyTextField.center;
[UIView animateWithDuration:0.3
animations:^{
self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y + 100);
}];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Ответ 11
Я предполагаю, что одним из способов было бы перемещение позиции всего вашего взгляда из (x, y) в (x, y-keybaardHeight), когда текстовое поле будет нажато и вернется обратно, когда клавиатура будет уволена, может показаться немного странным, вид просто появляется (возможно, это было бы плохо, если бы вы его оживили).
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect frame=self.view.frame;
frame.origin=CGPointMake(x...//set point here
self.view.frame=frame;
}
Ответ 12
Перетащите фреймворк, который я использую в своих проектах. Поддерживает автоматическое увольнение при нажатии вне первого ответчика или при прокрутке.
GTKeyboardHelper
Ответ 13
В дополнение к решению Amagrammer, если вы используете cocos2d в портретном режиме, измените эту строку:
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
:
[CCDirector sharedDirector].openGLView.frame = CGRectOffset([CCDirector sharedDirector].openGLView.frame, movement, 0);
Если вы используете cocos2d в ландшафтном режиме, сделайте вышеуказанное изменение и переключите значения up
в textFieldDidBeginEditing:
и textFieldDidEndEditing:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self animateTextField:textField up:NO];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[self animateTextField:textField up:YES];
}
Ответ 14
У меня была та же проблема, и нашлось, что GTKeyboardHelper - простой выход.
После перетаскивания рамки в вашем проекте включите заголовочный файл.
Загрузите и откройте пример проекта, а затем перетащите объект "Помощник клавиатуры" из раздела объектов в разделе xib в раздел объектов в построителе интерфейса проекта.
Перетащите все свои представления, чтобы быть дочерними элементами "Помощника клавиатуры".
Ответ 15
Как вы справляетесь с ситуацией, когда клавиатура вставлена, а кадр изменился с анимацией и прокручивается, поэтому текстовое поле не покрывается, оттуда, когда я выбираю другое текстовое поле (все еще редактируя первое текстовое поле), как я не могу воспроизвести анимация снова и просто прокрутите немного дальше, если необходимо? Проблема заключается в повторном воспроизведении всей анимации, когда она не нужна. Благодаря
Ответ 16
Пожалуйста, посмотрите мой комментарий в этом:
iPhone - Клавиатура скрывает TextField
Ответ 17
Просто сдвиньте представление вверх и вниз по мере необходимости:
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.currentTextField = nil;
[self animateTextField: textField up: NO];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.currentTextField resignFirstResponder];
return YES;
}
- (void) animateTextField:(UITextField*) textField up:(BOOL)up {
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView animateWithDuration:movementDuration animations:^{
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
}];
}
Не забудьте установить self
как UITextFieldDelegate
и как фактический textField delegate
.
(Спасибо Ammagrammer, это всего лишь более короткий ответ, используя блоки для анимации)
Ответ 18
У меня есть что-то еще, если хочешь. Дело в том, что вы хотите установить центр UIView в текстовое поле, которое вы редактируете.
До этого вам нужно сохранить INITIAL_CENTER, как CGPoint, от self.view.center и INITIAL_VIEW, как CGRect из self.view.frame в свойстве const.
Вы можете создать такой способ:
- (void) centerOn: (CGRect) fieldFrame {
// Set up the center by taking the original view center
CGPoint center = CGPointMake(INITIAL_CENTER.x,
INITIAL_CENTER.y - ((fieldFrame.origin.y + fieldFrame.size.height/2) - INITIAL_CENTER.y));
[UIView beginAnimations:@"centerViewOnField" context:nil];
[UIView setAnimationDuration:0.50];
if (CGRectEqualToRect(fieldFrame,INITIAL_VIEW)) {
self.view.frame = INITIAL_VIEW;
[self.view setCenter:INITIAL_CENTER];
} else {
[self.view setCenter:center];
}
[UIView commitAnimations];
}
Затем, на UITextFieldDelegate, вы должны вызвать centerOn: (CGRect) следующими способами:
textFieldDidBeginEditing: (UITextField *), в качестве параметра - рамку текстового поля, на которое вы хотите сосредоточиться.
И вы должны называть его в своем обработчике событий, где вы закрываете клавиатуру,
textFieldDidEndEditing: (UITextField *) может быть одним из способов сделать это, поставив INITIAL_VIEW в качестве параметра centerOn: (CGRect).
Ответ 19
Я верю в более новые версии iOS (6.1+, возможно, даже раньше), основной вид, по крайней мере для UITableView, автоматически сжимается при всплывании клавиатуры. Поэтому вам нужно только сделать текстовое поле видимым в этом представлении. В init
:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
то
- (void)keyboardWasShown:(NSNotification*)notification
{
// Scroll the text field into view so it not under the keyboard.
CGRect rect = [self.tableView convertRect:inputView.bounds fromView:inputView];
[self.tableView scrollRectToVisible:rect animated:YES];
}
Ответ 20
https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example Я надеюсь, что это решение помогло. Все они написаны Swift 3.
//
// ViewController.swift
// Shift Keyboard Example
//
// Created by Zulwiyoza Putra on 11/23/16.
// Copyright © 2016 Zulwiyoza Putra. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
//connecting textfield from storyboard
@IBOutlet weak var textField: UITextField!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
subscribeToKeyboardNotifications()
}
override func viewDidAppear(_ animated: Bool) {
self.textField.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
unsubscribeFromKeyboardNotifications()
}
//Hide keyboard after finished editing
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
//Setup view before keyboard appeared
func keyboardWillAppear(_ notification:Notification) {
view.frame.origin.y = 0 - getKeyboardHeight(notification)
}
//Setup view before keyboard disappeared
func keyboardWillDisappear(_ notification: Notification) {
view.frame.origin.y = 0
}
//Getting keyboard height
func getKeyboardHeight(_ notification:Notification) -> CGFloat {
let userInfo = notification.userInfo
let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
return keyboardSize.cgRectValue.height
}
//Subscribing to notifications to execute functions
func subscribeToKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(_:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: .UIKeyboardWillHide, object: nil)
}
//Unsubscribing from notifications
func unsubscribeFromKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
}