답변:
일반적인 해결 방법은 애니메이션을 사용하여 필드 (및 그 위에있는 모든 항목)를 위로 밀었 다가 완료되면 아래로 내리는 것입니다. 텍스트 필드와 일부 다른 항목을 다른보기에 넣고보기를 하나의 단위로 밀어야 할 수 있습니다. (나는 이것을 "접착 판"에서와 같이 "판"이라고 부르지 만 그것은 나 뿐이다). 그러나 여기에 당신이 공상을 할 필요가 없다면 일반적인 아이디어가 있습니다.
- (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];
}
이것은 uitextfields 슬라이딩 나를 위해 놀라운 일을했습니다.
특히 텍스트 필드의 위치에 따라 슬라이드 애니메이션 거리를 계산하는 이점이 있습니다.
IQKeyboardManager 는 코드 줄 없이이 작업을 수행합니다 . 관련 소스 파일을 프로젝트로 끌어서 놓기 만하면 됩니다. IQKeyboardManager 는 또한 Device Orientation , Automatic UIToolbar Management , keyboardDistanceFromTextField 및 생각보다 훨씬 많은 것을 지원합니다.
다음은 제어 흐름 차트입니다.
1 단계는 : - 글로벌 알림을 추가 UITextField
, UITextView
및 UIKeyboard
싱글 클래스. 나는 그것을 IQKeyboardManager 라고 불렀습니다 .
2 단계 :- 발견 된 UIKeyboardWillShowNotification
경우 UITextFieldTextDidBeginEditingNotification
또는 알림이있는 경우 계층 구조 에서 인스턴스 UITextViewTextDidBeginEditingNotification
를 가져 오십시오 . 제대로 밝히기 위해서는 / 그것에서 의 프레임을 조정해야합니다.topMostViewController
UIWindow.rootViewController
UITextField
UITextView
topMostViewController.view
Step3 :-topMostViewController.view
첫 번째 응답 UITextField
/에 대한 예상 이동 거리 계산 UITextView
.
Step4 :-topMostViewController.view.frame
예상 이동 거리에 따라 위 / 아래 로 이동 했습니다.
5 단계 : - 발견하는 경우 UIKeyboardWillHideNotification
, UITextFieldTextDidEndEditingNotification
또는 UITextViewTextDidEndEditingNotification
통지 후 다시 얻으려고 topMostViewController
로부터 인스턴스를 UIWindow.rootViewController
계층 구조.
Step6 :-topMostViewController.view
원래 위치로 복원해야하는 계산 된 방해 거리 .
Step7 :-topMostViewController.view.frame
방해 된 거리에 따라 아래로 복원 .
Step8 :- 앱로드시 인스턴스화 된 싱글 톤 IQKeyboardManager 클래스 인스턴스이므로 앱의 모든 UITextField
/ UITextView
가 예상 이동 거리에 따라 자동으로 조정됩니다.
그게 다야
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];
}
UIApplicationDidEnterBackgroundNotification
않으면 홈 버튼을 누르고 앱으로 다시 들어 오면 더 아래로 이동하여보기 흉하고 버그가 생깁니다.
공식 솔루션은 어떻습니까 : 키보드 아래에있는 콘텐츠 이동
콘텐츠를 조정하려면 일반적으로 하나 이상의보기 크기를 일시적으로 조정하고 텍스트 개체가 계속 표시되도록 배치합니다. 키보드로 텍스트 개체를 관리하는 가장 간단한 방법은 UIScrollView 개체 (또는 UITableView와 같은 하위 클래스 중 하나)에 포함하는 것입니다. 키보드가 표시되면 스크롤보기의 콘텐츠 영역을 재설정하고 원하는 텍스트 개체를 위치로 스크롤하기 만하면됩니다. 따라서 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's 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;
}
UITableView
textField 셀 에서 동일한 문제에 직면했습니다 . 키보드 알림을 듣기 위해 다음 방법을 구현하여이 문제를 해결합니다.
여기에서 알림에 대한 관찰자 :
[[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
이것 좀 봐. 번거롭지 않습니다.
이 솔루션은 매우 깔끔합니다. 스토리 보드를 사용하는 경우 a에 텍스트 필드를 추가 UIScrollView
하고 클래스를로 변경 하기 만하면됩니다 TPKeyboardAvoidingScollView
. 스크롤 뷰는 키보드가 보일 때를 감지하고 적당한 거리에서 키보드 위로 스스로 이동하는 방식으로 확장됩니다. .NET Framework와 독립적이기 때문에 완벽한 솔루션 UIViewController
입니다. 필요한 모든 것은 위에서 언급 한 클래스 내에서 수행됩니다. 감사합니다 Michael Tyson et all.
아래는 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)
}
에서 좋은 연습이 있었다 편집 텍스트 필드가 모호하지 않고 지금은 죽은 (링크를 여기에 뒤로 링크는 다음과 같습니다 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 업데이트 후를 참조하십시오 .
다음은 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];
}
한 가지 방법은 텍스트 필드를 클릭하면 전체 뷰 위치를 (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;
}
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];
}
프로젝트에서 사용하는 프레임 워크를 드래그 앤 드롭합니다. 첫 번째 응답자 외부를 탭하거나 스크롤 할 때 자동 해제를 지원합니다.
필요에 따라보기를 위아래로 슬라이드하면됩니다.
- (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 덕분에 애니메이션에 블록을 사용하는 짧은 답변입니다)
당신이 원한다면 다른 것이 있습니다. 여기서 요점은 편집중인 텍스트 필드에서 UIView의 중앙을 설정하려는 것입니다.
그 전에 INITIAL_CENTER , self.view.center에서 CGPoint 로 저장 하고 INITIAL_VIEW 를 const 속성의 self.view.frame에서 CGRect 로 저장해야 합니다.
다음과 같은 방법을 만들 수 있습니다.
- (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) 의 매개 변수로 두는 방법 중 하나 일 수 있습니다 .
나는 최신 버전의 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's not under the keyboard.
CGRect rect = [self.tableView convertRect:inputView.bounds fromView:inputView];
[self.tableView scrollRectToVisible:rect animated:YES];
}
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)
}
}