[ios] 키보드가 입력 필드를 덮을 때만 뷰를 위로 이동
iPhone의 입력 화면을 만들려고합니다. 화면에는 많은 입력 필드가 있습니다. 대부분은 화면 상단에 있지만 하단에 두 개의 필드가 있습니다. 사용자가 화면 하단의 텍스트를 편집하려고하면 키보드가 나타나서 화면을 덮습니다. 이 일이 발생하면 화면을 위로 올리는 간단한 해결책을 찾았지만 결과적으로 화면이 항상 위로 이동하고 사용자가 편집하려고 할 때 화면 상단의 필드가 도달하지 않습니다.
하단 필드를 편집 할 때만 화면을 이동 시키는 방법 이 있습니까?
나는 내가 찾은이 코드를 사용하고 여기를 :
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 150
}
답변
이 문서 에서 문제는 Apple 에서 잘 설명 합니다. 이 페이지의 예제 코드 ( Listing 4-1
)는 필요한 것을 정확하게 수행하며 현재 편집이 키보드 아래에 있어야하는 경우에만보기를 스크롤합니다. 필요한 컨트롤 만 scrollViiew에 넣으면됩니다. 유일한 문제는 이것이 Objective-C이며 Swift..so에서 필요하다고 생각합니다.
변수 선언
var activeField: UITextField?
그런 다음이 방법을 추가하십시오
func registerForKeyboardNotifications()
{
//Adding notifies on keyboard appearing
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}
func deregisterFromKeyboardNotifications()
{
//Removing notifies on keyboard appearing
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(notification: NSNotification)
{
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.scrollEnabled = true
var info : NSDictionary = notification.userInfo!
var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeFieldPresent = activeField
{
if (!CGRectContainsPoint(aRect, activeField!.frame.origin))
{
self.scrollView.scrollRectToVisible(activeField!.frame, animated: true)
}
}
}
func keyboardWillBeHidden(notification: NSNotification)
{
//Once keyboard disappears, restore original positions
var info : NSDictionary = notification.userInfo!
var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.scrollView.scrollEnabled = false
}
func textFieldDidBeginEditing(textField: UITextField!)
{
activeField = textField
}
func textFieldDidEndEditing(textField: UITextField!)
{
activeField = nil
}
ViewController를 선언 UITextFieldDelegate
하고 초기화 메소드에서 올바른 대리자를 설정하십시오. ex :
self.you_text_field.delegate = self
그리고 registerForKeyboardNotifications
viewInit 및 deregisterFromKeyboardNotifications
exit 를 호출해야 합니다 .
편집 / 업데이트 : Swift 4.2 구문
func registerForKeyboardNotifications(){
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}
func deregisterFromKeyboardNotifications(){
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWasShown(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeField {
if (!aRect.contains(activeField.frame.origin)){
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}
@objc func keyboardWillBeHidden(notification: NSNotification){
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.scrollView.isScrollEnabled = false
}
func textFieldDidBeginEditing(_ textField: UITextField){
activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField){
activeField = nil
}
답변
여기 내 2 센트가 있습니다 :
https://github.com/hackiftekhar/IQKeyboardManager 를 사용해 보셨습니까?
Swift 또는 Objective-C를 매우 쉽게 설치할 수 있습니다.
작동 방식은 다음과 같습니다.
IQKeyboardManager (Swift) :-CocoaPods를 통해 IQKeyboardManagerSwift를 사용할 수 있습니다. Podfile에 다음 줄을 추가하기 만하면됩니다. (# 236)
pod 'IQKeyboardManagerSwift'
AppDelegate.swift에서 IQKeyboardManagerSwift 프레임 워크를 임포트하고 IQKeyboardManager를 활성화하십시오.
import IQKeyboardManagerSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
IQKeyboardManager.sharedManager().enable = true
// For Swift 4, use this instead
// IQKeyboardManager.shared.enable = true
return true
}
}
그리고 그게 다야. 쉬운!
답변
내가 완벽하게 작동하는 것으로 밝혀진 것은 다음과 같습니다.
func textFieldDidBeginEditing(textField: UITextField) {
if textField == email || textField == password {
animateViewMoving(true, moveValue: 100)
}
}
func textFieldDidEndEditing(textField: UITextField) {
if textField == email || textField == password {
animateViewMoving(false, moveValue: 100)
}
}
func animateViewMoving (up:Bool, moveValue :CGFloat){
let movementDuration:NSTimeInterval = 0.3
let movement:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations("animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
높이 값을 변경할 수도 있습니다. 모든 텍스트 필드에 사용하려면 “if 문”을 제거하십시오.
TextView와 같은 사용자 입력이 필요한 모든 컨트롤에이 기능을 사용할 수도 있습니다.
답변
하단 필드 를 편집 할 때만 화면을 이동 시키는 방법 이 있습니까?
비슷한 문제가 있었고 scrollView 를 사용 하지 않고 keyboardWillShow / Hide 메서드 내 if 문을 사용 하지 않고 매우 간단한 해결책 을 찾았습니다 .
func keyboardWillShow(notification: NSNotification) {
if bottomText.editing{
self.view.window?.frame.origin.y = -1 * getKeyboardHeight(notification)
}
}
func keyboardWillHide(notification: NSNotification) {
if self.view.window?.frame.origin.y != 0 {
self.view.window?.frame.origin.y += getKeyboardHeight(notification)
}
}
두 개의 텍스트 필드 만 있었기 때문에 이것은 좋은 해결책이었습니다.
전체보기 위로 이동 : 특정 텍스트 필드 (bottomText)가 편집 된 경우에만
전체보기를 아래로 이동 : 보기가 원래 위치에 있지 않은 경우에만
답변
키보드가 표시 될 때이 확장을 사용하여 UIView를 이동하십시오.
extension UIView {
func bindToKeyboard(){
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
@objc func keyboardWillChange(_ notification: NSNotification){
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let beginningFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - beginningFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
그런 다음 viewdidload에서 뷰를 키보드에 바인딩하십시오.
UiView.bindToKeyboard()
답변
대신 UITableViewController에서 이것을 구현하지 않는 이유는 무엇입니까? 키보드는 표시 될 때 텍스트 필드를 숨기지 않습니다.
답변
확장명이 포함 된 스위프트 4 (** 업데이트 됨 ) **
- 하나의 컨테이너에 버튼을 추가
- 컨테이너의 하단 제약 조건을 IBOutlet 컨테이너와 연결하십시오.
-
inViewDidLoad
self.containerDependOnKeyboardBottomConstrain = containerBtmConstrain self.watchForKeyboard()
-
다음 확장자를 추가하십시오
import UIKit private var xoAssociationKeyForBottomConstrainInVC: UInt8 = 0 extension UIViewController { var containerDependOnKeyboardBottomConstrain :NSLayoutConstraint! { get { return objc_getAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC) as? NSLayoutConstraint } set(newValue) { objc_setAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } func watchForKeyboard() { NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWasShown(notification:)), name:UIResponder.keyboardWillShowNotification, object: nil); NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name:UIResponder.keyboardWillHideNotification, object: nil); } @objc func keyboardWasShown(notification: NSNotification) { let info = notification.userInfo! guard let keyboardFrame: CGRect = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return } UIView.animate(withDuration: 0.3, animations: { () -> Void in self.containerDependOnKeyboardBottomConstrain.constant = -keyboardFrame.height self.view.layoutIfNeeded() }) } @objc func keyboardWillHide(notification: NSNotification) { UIView.animate(withDuration: 0.3, animations: { () -> Void in self.containerDependOnKeyboardBottomConstrain.constant = 0 self.view.layoutIfNeeded() }) } }