[ios] Swift를 사용하여 키보드로 뷰 이동

뷰의 아래쪽 절반에 텍스트 필드가있는 앱이 있습니다. 이것은 텍스트 필드에 입력 할 때 키보드가 텍스트 필드를 덮음을 의미합니다.

입력하는 동안보기를 위로 이동하여 입력하는 내용을 확인한 다음 키보드가 사라지면 원래 위치로 다시 이동하는 방법은 무엇입니까?

나는 모든 곳을 보았지만 모든 솔루션은 Obj-C에있는 것으로 보이며 아직 변환 할 수는 없습니다.

도움을 주시면 감사하겠습니다.



답변

한 textField에서 다른 textField 로의 전환을 처리하지 않는 솔루션은 다음과 같습니다.

 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(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.frame.origin.y -= keyboardSize.height
    }
}

func keyboardWillHide(notification: NSNotification) {
    self.view.frame.origin.y = 0
}

이 문제를 해결하려면 두 기능 keyboardWillShow/Hide을 다음과 같이 바꾸십시오 .

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        if view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    if view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

스위프트 3.0 편집 :

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

SWIFT 4.0 편집 :

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

스위프트 4.2 편집 :

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}


답변

코드가 필요없는 가장 쉬운 방법 :

  1. Spring 애니메이션 프레임 워크를 아직 사용하고 있지 않은 경우 KeyboardLayoutConstraint.swift를 다운로드 하고 파일을 프로젝트에 추가 (끌어다 놓기)하십시오.
  2. 스토리 보드에서보기 또는 텍스트 필드에 대한 맨 아래 제한 조건을 작성하고 제한 조건을 두 번 클릭 한 후 Identity Inspector에서 클래스를 NSLayoutConstraint에서 KeyboardLayoutConstraint로 변경하십시오.
  3. 끝난!

객체는 키보드와 함께 자동으로 위로 움직입니다.


답변

이 스레드에서 널리 사용되는 답변 중 하나는 다음 코드를 사용합니다.

func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 150
}

뷰를 정적 양만큼 상쇄하는 데 명백한 문제가 있습니다. 한 장치에서는 좋아 보이지만 다른 크기 구성에서는 나빠 보일 것입니다. 키보드 높이를 가져와 오프셋 값으로 사용해야합니다.

다음 은 모든 장치에서 작동 하고 사용자가 입력하는 동안 예측 텍스트 필드를 숨기는 가장자리를 처리 하는 솔루션입니다 .

해결책

아래에서 중요하게, self.view.window를 객체 매개 변수로 전달합니다. 이렇게하면 키와 같은 키보드의 데이터가 제공됩니다!

@IBOutlet weak var messageField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
}

func keyboardWillHide(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!
    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    self.view.frame.origin.y += keyboardSize.height
}

모든 장치에서 멋지게 보이게하고 사용자가 예측 텍스트 필드를 추가하거나 제거하는 경우를 처리합니다.

func keyboardWillShow(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!
    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size

    if keyboardSize.height == offset.height {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y -= keyboardSize.height
        })
    } else {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y += keyboardSize.height - offset.height
        })
    }
}

관찰자 제거

불필요한 메시지가 전송되지 않도록보기를 떠나기 전에 관찰자를 제거하는 것을 잊지 마십시오.

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}

의견의 질문에 따라 업데이트 :

텍스트 필드가 두 개 이상인 경우 view.frame.origin.y가 0인지 확인할 수 있습니다.

func keyboardWillShow(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!

    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size

    if keyboardSize.height == offset.height {
        if self.view.frame.origin.y == 0 {
            UIView.animateWithDuration(0.1, animations: { () -> Void in
                self.view.frame.origin.y -= keyboardSize.height
            })
        }
    } else {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y += keyboardSize.height - offset.height
        })
    }
     print(self.view.frame.origin.y)
}


답변

이것을 뷰 컨트롤러에 추가하십시오. 매력처럼 작동합니다. 그냥 값을 조정하십시오.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil);
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil);
}

@objc func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}
@objc func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 150
}


답변

하나의 페이지에서 다른 키보드 및 다른 텍스트보기 / 필드와 함께 작동하도록 답변 중 하나를 약간 개선했습니다.

관찰자 추가 :

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

func keyboardWillHide() {
    self.view.frame.origin.y = 0
}

func keyboardWillChange(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if YOURTEXTVIEW.isFirstResponder {
            self.view.frame.origin.y = -keyboardSize.height
        }
    }
}

관찰자를 제거하십시오.

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}


답변

광고 나 판촉 또는 스팸 이 아니라 좋은 해결책입니다. 나는이 질문에 거의 30 가지 답변이 있다는 것을 알고 놀랍습니다. 이 아름다운 GitHub 프로젝트 에 대해 한 번도 언급하지 않아서 당신을 위해 더 잘하고 있습니다. 모든 답변은 뷰를 위로 이동시킵니다. 이 IQKeyboardManager와 관련된 모든 문제를 방금 해결했습니다. 별 13000 개가 있습니다.
swift를 사용하는 경우 podfile에 이것을 추가하십시오.

pod 'IQKeyboardManagerSwift'

그런 다음 AppDelegate.swift 내부에서 import IQKeyboardManagerSwift

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

      IQKeyboardManager.shared.enable = true // just add this line

      return true
    }
}

IQKeyboardManager.shared.enable = true활성화하기 위해 라인 추가이
솔루션은 생산을 위해 반드시 필요한 것입니다.


답변

블랙 스크린 오류의 경우 (Swift 4 & 4.2) .

검은 화면 문제를 해결했습니다. 확인 된 해결 방법 탭핑 후 키보드 높이가 변경되어 검은 색 화면이 나타납니다.

UIKeyboardFrameBeginUserInfoKey 대신 UIKeyboardFrameEndUserInfoKey 를 사용해야합니다.

var isKeyboardAppear = false

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if !isKeyboardAppear {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0{
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
        isKeyboardAppear = true
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if isKeyboardAppear {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0{
                self.view.frame.origin.y += keyboardSize.height
            }
        }
         isKeyboardAppear = false
    }
}