iOS SDK를 사용하여 :
나는이 UIView
와 UITextField
키보드를 가지고 있음을의. 나는 그것을 할 수 있어야합니다.
-
UIScrollView
키보드를 불러 온 후 다른 텍스트 필드를 보려면 의 내용을 스크롤 할 수 있습니다. -
자동으로 “점프”(위로 스크롤) 또는 단축
나는 내가 필요하다는 것을 안다 UIScrollView
. 내의 클래스를 변경 해봤 UIView
A를 UIScrollView
하지만, 난 여전히 위 또는 아래로 텍스트 상자를 스크롤 할 수 없어요.
a UIView
와 a 가 모두 필요 UIScrollView
합니까? 하나는 다른 안으로 들어가나요?
활성 텍스트 필드로 자동 스크롤하려면 무엇을 구현해야합니까?
가능한 한 많은 구성 요소 설정이 Interface Builder에서 수행됩니다. 필요한 코드 만 작성하고 싶습니다.
참고 : 내가 작업하고 있는 UIView
(또는 UIScrollView
)은 정상적으로 작동 UITabBar
해야하는 탭 바 ( )에 의해 나타납니다 .
편집 : 키보드가 나타날 때만 스크롤 막대를 추가하고 있습니다. 필요하지는 않지만 사용자가 텍스트 상자를 스크롤하고 변경할 수 있기 때문에 더 나은 인터페이스를 제공한다고 생각합니다.
UIScrollView
키보드가 위아래로 움직일 때의 프레임 크기를 변경하는 곳에서 작동 합니다. 나는 단순히 다음을 사용하고 있습니다 :
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Keyboard becomes visible
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50); //resize
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//keyboard will hide
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height + 215 - 50); //resize
}
그러나 이것은 가시 영역의 하단 텍스트 필드를 자동으로 “위로 이동”하거나 가운데에 두지 않습니다. 이것이 내가 정말로 원하는 것입니다.
답변
-
ScrollView
iPhone 화면에 맞지 않는 내용 만 있으면됩니다. (ScrollView
구성 요소의 슈퍼 뷰로를 추가하는 경우TextField
키보드가 나타날 때 스크롤 필요하지 않습니다.) -
방지하는 표준 방법
TextField
키보드로 키보드 은 키보드가 표시 될 때마다보기를 위 / 아래로 이동하는 것입니다.
샘플 코드는 다음과 같습니다.
#define kOFFSET_FOR_KEYBOARD 80.0
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:mailTf])
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// register for keyboard notifications
[[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];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
답변
또한 UIScrollView
여러 개의 작곡에 많은 문제가 UITextFields
있었고 그 중 하나 이상이 편집 중 키보드에 의해 가려 질 수 있습니다.
UIScrollView
스크롤이 제대로되지 않으면 고려해야 할 사항이 있습니다 .
1) contentSize가 UIScrollView
프레임 크기 보다 큰지 확인하십시오 . 이해하는 방법은 UIScrollViews
(가)이다 UIScrollView
contentSize에 정의 된 내용에 보는 창 같다. 따라서 UIScrollview
어디에서나 스크롤하려면 contentSize가.보다 커야합니다 UIScrollView
. 그렇지 않으면 contentSize에 정의 된 모든 항목이 이미 표시되므로 스크롤이 필요하지 않습니다. BTW, 기본 contentSize =CGSizeZero
.
2) 이제는 이것이 UIScrollView
실제로 “콘텐츠”의 창 이라는 것을 이해 했으므로 키보드가 UIScrollView's
보기 “창”을 가리지 않도록하는 방법은 키보드가 UIScrollView
있을 때 UIScrollView
창 을 갖도록 크기를 조정하는 것입니다. 크기는 원래 UIScrollView
프레임 크기 와 높이에서 키보드 높이를 뺀 크기 입니다. 이렇게하면 창이 작은 가시 영역 만 확보 할 수 있습니다.
3) 캐치가 있습니다 : 처음 이것을 구현했을 때 CGRect
편집 된 텍스트 필드 를 가져 와서 UIScrollView's
scrollRecToVisible 메소드를 호출 해야한다고 생각 했습니다 . UITextFieldDelegate
메서드 textFieldDidBeginEditing
를 호출 하여 메서드 를 구현했습니다 scrollRecToVisible
. 이것은 실제로 스크롤 것이 이상한 부작용과 협력 스냅 을 UITextField
위치로. 가장 오랫동안 나는 그것이 무엇인지 알 수 없었습니다. 그런 다음 textFieldDidBeginEditing
Delegate 메서드를 주석 처리하고 모두 작동합니다 !! (???). 그것이 UIScrollView
실제로 암시 적으로 현재 편집 UITextField
된 것을 볼 수있는 창에 암시 적으로 가져 온다고 생각합니다 . UITextFieldDelegate
메소드의 구현 과 이후의 호출 scrollRecToVisible
은 중복되었으며 이상한 부작용의 원인이었습니다.
그래서 여기에 제대로 스크롤하는 단계입니다 UITextField
A의 UIScrollView
장소 때 키보드가 나타납니다으로는.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
CGSize scrollContentSize = CGSizeMake(320, 345);
self.scrollView.contentSize = scrollContentSize;
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the scrollview
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height += (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
- (void)keyboardWillShow:(NSNotification *)n
{
// This is an ivar I'm using to ensure that we do not do the frame size adjustment on the `UIScrollView` if the keyboard is already shown. This can happen if the user, after fixing editing a `UITextField`, scrolls the resized `UIScrollView` to another `UITextField` and attempts to edit the next `UITextField`. If we were to resize the `UIScrollView` again, it would be disastrous. NOTE: The keyboard notification will fire even when the keyboard is already shown.
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- 키보드 알림 등록
viewDidLoad
- 키보드 노 티피 케이션 등록 해제
viewDidUnload
- 이 있는지 확인
contentSize
설정하고보다 큰UIScrollView
에서viewDidLoad
- 축소 를
UIScrollView
키보드가있는 경우 - 다시 되돌리기
UIScrollView
키보드가 사라질 때. - 키보드 알림은이 때마다 전송되기 때문에 키보드가 이미 화면에 표시되어있는 경우 감지하는 바르를 사용하여
UITextField
키보드를 피하기 위해 이미 존재하는 경우에도 탭되고 축소 을UIScrollView
이미 때 수축을
한 가지주의해야 할 점은 UIKeyboardWillShowNotification
다른 키보드를 탭하면 키보드가 이미 화면에 있어도 작동 한다는 것 UITextField
입니다. UIScrollView
키보드가 이미 화면에있을 때 크기 조정을 피하기 위해 ivar을 사용 하여이 문제를 해결했습니다 . UIScrollView
키보드가 이미있을 때 실수로 크기를 조정하면 재앙이 생길 것입니다!
이 코드가 여러분의 많은 두통을 덜어 주길 바랍니다.
답변
docs에 제공된대로 실제로 Apple 구현을 사용하는 것이 가장 좋습니다 . 그러나 이들이 제공하는 코드에 결함이 있습니다. keyboardWasShown:
주석 바로 아래 에있는 부분을 다음으로 대체하십시오 .
NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);
CGPoint origin = activeRect.origin;
origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin)) {
CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
[backScrollView setContentOffset:scrollPoint animated:YES];
}
Apple 코드의 문제점은 다음과 같습니다. (1) 포인트가 뷰의 프레임 내에 있는지 항상 계산하지만 포인트 ScrollView
이므로 이미 스크롤되어 해당 오프셋을 고려해야합니다.
origin.y -= scrollView.contentOffset.y
(2) 그들은 키보드의 높이에 따라 contentOffset을 이동 시키지만, 반대를 원합니다 ( contentOffset
화면에 보이지 않는 높이가 아닌 높이 로 이동하고 싶습니다 ).
activeField.frame.origin.y-(aRect.size.height)
답변
다음 textFieldDidBeginEditting
과 같이 textFieldDidEndEditing
함수 를 호출하십시오 [self animateTextField:textField up:YES]
.
-(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 = -130; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: @"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
이 코드가 도움이 되길 바랍니다.
스위프트 2에서
func animateTextField(textField: UITextField, up: Bool)
{
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up
{
movement = movementDistance
}
else
{
movement = -movementDistance
}
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
func textFieldDidBeginEditing(textField: UITextField)
{
self.animateTextField(textField, up:true)
}
func textFieldDidEndEditing(textField: UITextField)
{
self.animateTextField(textField, up:false)
}
스위프트 3
func animateTextField(textField: UITextField, up: Bool)
{
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up
{
movement = movementDistance
}
else
{
movement = -movementDistance
}
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
func textFieldDidBeginEditing(textField: UITextField)
{
self.animateTextField(textField: textField, up:true)
}
func textFieldDidEndEditing(textField: UITextField)
{
self.animateTextField(textField: textField, up:false)
}
답변
TextFields를 사용하는 경우 :
1a) 사용 Interface Builder
: 모든 텍스트 필드 선택 => 편집 => 포함 => ScrollView
1b) UIScrollView에 scrollField라는 텍스트 필드를 수동으로 포함
2) 세트 UITextFieldDelegate
3) 각각을 설정 textField.delegate = self;
하거나Interface Builder
)
4) 복사 / 붙여 넣기 :
- (void)textFieldDidBeginEditing:(UITextField *)textField {
CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
[scrollView setContentOffset:scrollPoint animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[scrollView setContentOffset:CGPointZero animated:YES];
}
답변
들어 범용 솔루션 , 여기에 구현하기위한 나의 접근 방식이었다 IQKeyboardManager을 .
1 단계 : – 의 I 추가 글로벌 통지 UITextField
, UITextView
및 UIKeyboard
의 싱글 클래스입니다. 나는 그것을 IQKeyboardManager 라고 부른다 .
2 단계 : – 만약 발견 UIKeyboardWillShowNotification
, UITextFieldTextDidBeginEditingNotification
또는 UITextViewTextDidBeginEditingNotification
알림, 내가 좀하려고 topMostViewController
로부터 인스턴스를 UIWindow.rootViewController
계층 구조. 제대로 밝히기 위해서는 UITextField
/ UITextView
그것에서 topMostViewController.view
의 프레임을 조정해야합니다.
Step3 :-topMostViewController.view
첫 번째 반응 UITextField
/에 대한 예상 이동 거리를 계산 했습니다 UITextView
.
4 단계는 : – 나는 이동 topMostViewController.view.frame
예상 이동 거리에 따라 UP / DOWN.
Step5 :-UIKeyboardWillHideNotification
, UITextFieldTextDidEndEditingNotification
또는 UITextViewTextDidEndEditingNotification
알림 이 발견 되면 계층 topMostViewController
에서 인스턴스를 다시 가져 오려고 시도합니다 UIWindow.rootViewController
.
Step6 :-topMostViewController.view
원래 거리 로 복원해야하는 방해 거리를 계산 했습니다.
Step7 :-topMostViewController.view.frame
방해 거리에 따라 회복 했습니다.
Step8 :- 앱로드시 싱글 톤 IQKeyboardManager 클래스 인스턴스를 인스턴스화 했으므로 앱의 모든 UITextField
/ UITextView
가 예상 이동 거리에 따라 자동으로 조정됩니다.
그게 다야 IQKeyboardManager을 당신을 위해 할 코드의 NO LINE 정말! 관련 소스 파일을 프로젝트로 끌어서 놓기 만하면됩니다. IQKeyboardManager 는 또한 장치 방향 , 자동 UI 도구 모음 관리 , KeybkeyboardDistanceFromTextField 및 훨씬 더 많은 것을 지원합니다.
답변
필자는 키보드에서 벗어나는 모든 텍스트 필드를 이동시키는 범용 드롭 UIScrollView
인 UITableView
및 UICollectionView
서브 클래스를 구성했습니다.
키보드가 나타나려고 할 때 서브 클래스는 편집 할 서브 뷰를 찾고 키보드 팝업과 일치하는 애니메이션을 사용하여 뷰가 표시되도록 프레임과 컨텐츠 오프셋을 조정합니다. 키보드가 사라지면 이전 크기로 복원됩니다.
기본적으로 모든 설정, 즉 UITableView
기반 인터페이스 또는 수동으로 배치 된보기로 구성된 설정에서 작동해야합니다 .
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)