UIKeyboardBoundsUserInfoKey被废弃,什么用呢?
-
25-09-2019 - |
题
我在工作上应用程序使用3.2sdk。我处理得到的键盘大小,以防止我的文本区域从开玩笑背后。
我得到一个警告在工业化->UIKeyboardBoundsUserInfoKey使用什么我应该使用,而不是不要得到这个警告?
解决方案
我打了以前提供的解决方案,但仍然有问题。以下是我想出了代替:
- (void)keyboardWillShow:(NSNotification *)aNotification {
[self moveTextViewForKeyboard:aNotification up:YES];
}
- (void)keyboardWillHide:(NSNotification *)aNotification {
[self moveTextViewForKeyboard:aNotification up:NO];
}
- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
NSDictionary* userInfo = [aNotification userInfo];
// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
// Animate up or down
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect newFrame = textView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1);
textView.frame = newFrame;
[UIView commitAnimations];
}
其他提示
从 文档 对于 UIKeyboardBoundsUserInfoKey
:
关键的一NSValue对象包含一个CGRect标识的界限矩形的键盘在窗口坐标。这个数值是足够获得的大小键盘。如果你想得到原籍国的屏幕上的键盘(之前或之后的动画)使用价值从用户获得信息的词典过UIKeyboardCenterBeginUserInfoKey或UIKeyboardCenterEndUserInfoKey常数。 使用UIKeyboardFrameBeginUserInfoKey或UIKeyboardFrameEndUserInfoKey关键替代。
苹果建议实施一个方便的程序如此(可以实现为一个类别之外 UIScreen
):
+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}
恢复窗口调整的键盘框架大小的性质。
我花了一种不同的方法,其中涉及检查设备向:
CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;
您简单地使用以下代码:
//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//instead of Upper line we can use either next line or nextest line.
//NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
以下代码解决了问题 Jay的答案, 它假设, UIKeyboardWillShowNotification
不会再次当键盘已经存在。
打字的时候的日本/中国的键盘,iOS火灾的一个额外的 UIKeyboardWillShowNotification
与新的键盘框架即使键盘就已经存在,导致高度 self.textView
正在减少的第二次中的原始代码。
这降低了 self.textView
几乎什么都没有。然后它就变得不可能恢复从这个问题,因为我们只期待一个单 UIKeyboardWillHideNotification
下一时间的键盘被驳回。
而不是减去增加的高度 self.textView
这取决于是否键盘是显示隐藏在原始代码,以下只是代码计算出的最大可能高度 self.textView
减后的高度上的键盘屏幕上。
这个假设 self.textView
是想要填满整个图景控制器,而且也没有其他子视图,需要的是可见的。
- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif {
NSDictionary* userInfo = [notif userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrameInWindowsCoordinates;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates];
[self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates
withAnimationDuration:animationDuration
animationCurve:animationCurve];
}
- (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates
withAnimationDuration:(NSTimeInterval)duration
animationCurve:(UIViewAnimationCurve)curve
{
CGRect fullFrame = self.view.frame;
CGRect keyboardFrameInViewCoordinates =
[self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];
// Frame of the keyboard that intersects with the view. When keyboard is
// dismissed, the keyboard frame still has width/height, although the origin
// keeps the keyboard out of the screen.
CGRect keyboardFrameVisibleOnScreen =
CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates);
// Max frame availble for text view. Assign it to the full frame first
CGRect newTextViewFrame = fullFrame;
// Deduct the the height of any keyboard that's visible on screen from
// the height of the text view
newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height;
if (duration)
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
}
// Adjust the size of the text view to the new one
self.textView.frame = newTextViewFrame;
if (duration)
{
[UIView commitAnimations];
}
}
还有,不要忘记注册的键盘的通知在viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter];
[notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil];
[notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil];
}
关于拆分的调整代码成两部分
为什么控调整的代码被分成两个部分(resizeTextViewWithKeyboardNotification:
和 resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
)是解决的另一个问题时键盘上仍然存在通过一个推动从一个角度控制器到另一个(见 我如何检测iOS键盘时,它保持了之间的控制器吗?).
由于键盘已经出现前景控制器是推动,没有其他的键盘的通知,正在产生,并因此无法调整 textView
根据这些键盘的通知。
上述代码(以及原始代码),调整大小 self.textView
因此工作时的键盘上显示 后 该图已经加载。
我的解决方案是建立一个单独的存储最后一个键盘的坐标,并在 - viewDidAppear:
的viewController,呼叫:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Resize the view if there's any keyboard presence before this
// Only call in viewDidAppear as we are unable to convertRect properly
// before view is shown
[self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame]
withAnimationDuration:0
animationCurve:0];
}
UASKeyboard
是我单独在这里。理想情况下,我们应该叫这个 - viewWillAppear:
, 但以我的经验(至少在6), convertRect:fromView:
方法,我们需要利用在 resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
不适当地转换键盘框架的图坐标的前景完全是可见的。
只要使用UIKeyboardFrameBeginUserInfoKey
或UIKeyboardFrameEndUserInfoKey
键代替UIKeyboardBoundsUserInfoKey
@Jason,您的代码,如果除了一个点细
目前,你实际上并没有任何动画和视图只会'流行”到新size.height。
您必须指定一个状态从中动画。动画是一种的(从状态) - >(到状态)的事
幸运的是一个指定视图作为(从状态)。
的当前状态非常方便的方法[UIView setAnimationBeginsFromCurrentState:YES];
如果您之后beginAnimations添加该行右:情境:你的代码完美的作品。
- (CGSize)keyboardSize:(NSNotification *)aNotification {
NSDictionary *info = [aNotification userInfo];
NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGSize keyboardSize;
if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) {
_screenOrientation = orientation;
if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize = [beginValue CGRectValue].size;
} else {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
}
} else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) {
// We didn't rotate
if (_screenOrientation == orientation) {
if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize = [beginValue CGRectValue].size;
} else {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
}
// We rotated
} else if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
} else {
keyboardSize = [beginValue CGRectValue].size;
}
}
return keyboardSize;
}
其工作像这样
这是保存按钮底部
的约束@IBOutlet weak var saveBtnBottom: NSLayoutConstraint!
@IBOutlet weak var nameText: UITextField!
内部viewDidLoad中
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
nameText.delegate = self
这是功能我们需要
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
nameText.resignFirstResponder()
return true
}
@objc func keyBoardWillShow(notification: Notification){
if let userInfo = notification.userInfo as? Dictionary<String, AnyObject>{
let frame = userInfo[UIResponder.keyboardFrameEndUserInfoKey]
let keyBoardRect = frame?.cgRectValue
if let keyBoardHeight = keyBoardRect?.height {
self.saveBtnBottom.constant = keyBoardHeight
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}
}
}
@objc func keyBoardWillHide(notification: Notification){
self.saveBtnBottom.constant = 30.0
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}