[swift] Swift의 userInfo에서 키보드 크기 가져 오기
키보드가 나타날 때 뷰를 위로 이동하는 코드를 추가하려고 시도했지만 Objective-C 예제를 Swift로 변환하는 데 문제가 있습니다. 나는 약간의 진전을 이루었지만 특정 라인에 갇혀 있습니다.
다음은 내가 따라온 두 가지 자습서 / 질문입니다.
Swift
http://www.ioscreator.com/tutorials/move-view-when-keyboard-appears를 사용하여 키패드가 나타날 때 UIViewController의 콘텐츠를 위로 이동하는 방법
현재 가지고있는 코드는 다음과 같습니다.
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func keyboardWillShow(notification: NSNotification) {
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
let frame = self.budgetEntryView.frame
frame.origin.y = frame.origin.y - keyboardSize
self.budgetEntryView.frame = frame
}
func keyboardWillHide(notification: NSNotification) {
//
}
현재이 줄에 오류가 발생합니다.
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
누군가가이 코드 줄이 무엇인지 알려줄 수 있다면 나머지는 직접 알아 내야합니다.
답변
라인에 몇 가지 문제가 있습니다.
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
notification.userInfo
선택적 사전을 반환[NSObject : AnyObject]?
하므로 값에 액세스하기 전에 래핑을 해제해야합니다.- Objective-C
NSDictionary
는 Swift 네이티브 사전에 매핑되므로dict[key]
값에 액세스하려면 사전 아래 첨자 구문 ( )을 사용해야합니다. NSValue
호출 할 수 있도록 값을 캐스트해야CGRectValue
합니다.
이 모든 것은 선택적 할당, 선택적 체인 및 선택적 캐스트의 조합으로 달성 할 수 있습니다.
if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
}
} else {
// no userInfo dictionary in notification
}
또는 한 단계로 :
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
}
Swift 3.0.1 (Xcode 8.1) 업데이트 :
if let userInfo = notification.userInfo {
if let keyboardSize = userInfo[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
}
} else {
// no userInfo dictionary in notification
}
또는 한 단계로 :
if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
}
Swift 5 (Xcode 11.6) 업데이트 :
guard let userInfo = notification.userInfo,
let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
이전 iOS 장치에서 처음 표시 한 후 키보드가 초기 렌더링 높이를 변경하므로 keyboardFrameEndUserInfoKey
대신 사용 하는 것이 좋습니다 keyboardFrameBeginUserInfoKey
.
답변
더 적은 코드의 경우 THIS를 살펴보십시오.
정말 도움이되었습니다. 뷰 컨트롤러에 뷰 제약을 포함하고 추가 한 두 옵저버를 사용하기 만하면됩니다. 그런 다음 다음 방법을 사용하십시오 (여기서는 tableView를 이동한다고 가정합니다)
func keyboardWillShow(sender: NSNotification) {
if let userInfo = sender.userInfo {
if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {
tableViewBottomConstraint.constant = keyboardHeight
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}
}
과
func keyboardWillHide(sender: NSNotification) {
if let userInfo = sender.userInfo {
if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {
tableViewBottomConstraint.constant = 0.0
UIView.animateWithDuration(0.25, animations: { () -> Void in self.view.layoutIfNeeded() })
}
} }
답변
뷰 자체를 조작하는 대신 스토리 보드를 사용하는 경우 자동 레이아웃을 활용할 수 있습니다.
(이것은 Nicholas ‘s Answer의 정리 된 버전입니다)
키보드의 모양과 사라짐을 알리도록 알림 센터를 설정하십시오.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}
관찰자가 더 이상 필요하지 않으면 제거해야합니다.
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}
스토리 보드 내에서 하단 제약을 설정합니다. 해당 제약의 출구를 만듭니다.
키보드가 표시되거나 숨겨 질 때 제약 조건의 상수 속성을 설정합니다.
func keyboardWillShow(notification: NSNotification) {
guard let keyboardHeight = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue.size.height else {
return
}
nameOfOutlet.constant = keyboardHeight
view.layoutIfNeeded()
}
func keyboardWillHide(notification: NSNotification) {
nameOfOutlet.constant = 0.0
view.layoutIfNeeded()
}
이제 키보드가 나타나거나 사라질 때마다 자동 레이아웃이 모든 것을 처리합니다.
답변
스위프트 2
func keyboardWasShown(notification:NSNotification) {
guard let info:[NSObject:AnyObject] = notification.userInfo,
let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size else { return }
let insets:UIEdgeInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, keyboardSize.height, 0.0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
스위프트 3
func keyboardWasShown(notification:NSNotification) {
guard let info:[AnyHashable:Any] = notification.userInfo,
let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size else { return }
let insets:UIEdgeInsets = UIEdgeInsets(top: self.scrollView.contentInset.top, left: 0.0, bottom: keyboardSize.height, right: 0.0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
답변
이것은 나를 도왔습니다 : https://developer.apple.com/library/ios/samplecode/UICatalog/Listings/Swift_UICatalog_TextViewController_swift.html
let userInfo = notification.userInfo!
let animationDuration: NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as NSNumber).doubleValue
let keyboardScreenBeginFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as NSValue).CGRectValue()
let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
답변
이 한 줄을 줄에 사용할 수 있습니다.
var keyboardSize:CGSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue().size
답변
Swift 3 : 업데이트
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}