在导航控制器推/动画动画期间,键盘较暗,然后处于最终状态。在动画结束时,这个黑色背景视图就消失了。轻(白色)键盘样式没有这种效果。
如何摆脱这种黑色背景?
我已经尝试将窗口颜色设置为白色并将导航控制器背景设置为白色。
视频
https://www.dropbox.com/s/z1grj821fj306th/Untitled.mov?dl=0
截图:
答案 0 :(得分:0)
选项 1
最简单的解决方案是通过将其背景颜色设置为黑色或白色(取决于您的键盘是浅色还是深色)来禁用键盘透明度:
myTextField.becomeFirstResponder()
guard UIDevice().userInterfaceIdiom == .phone else {
return;
}
//keyboard window should be there now, look for it:
var keyboardWindow: UIWindow?
for window in UIApplication.shared.windows.reversed() {
if String(describing: type(of: window)) == "UIRemoteKeyboardWindow" {
keyboardWindow = window
break
}
}
keyboardWindow?.rootViewController?.view.subviews.first?.backgroundColor = .black
选项 2
如果你不喜欢这个,我有一个看起来工作得很好的 hack,至少在 iOS 14 中。它会导致键盘向上滑动动画发生在推动画中,而不是之后。它依赖于在推送之前通过添加临时文本字段来显示键盘。
每当您想推送 VC 时运行此代码:
guard UIDevice().userInterfaceIdiom == .phone else {
// fix doesn't apply to iPad, push or perform segue:
self.performSegue(withIdentifier: "mySegue", sender: self)
// navigationController?.pushViewController(destinationVC, animated: true)
return;
}
//create text field with matching settings so keyboard will look the same as its destination
let tempTextField = UITextField.init()
tempTextField.keyboardType = .default
tempTextField.keyboardAppearance = .light
tempTextField.autocorrectionType = .default
view.addSubview(tempTextField)
//show keyboard, then right after push VC, then discard the text field
//make sure destination text field calls becomeFirstResponder() in its VC's viewDidLoad()
tempTextField.becomeFirstResponder()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0/60.0) {
// push or perform segue:
self.performSegue(withIdentifier: "mySegue", sender: self)
// navigationController?.pushViewController(destinationVC, animated: true)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
tempTextField.removeFromSuperview()
}
}
选项 3
我通过将推滑动画复制到键盘对选项 2 进行了改进,基本上可以满足您的要求。还可以选择在滑入过程中也保持向上滑动的动画,试试看吧。
只要你想推送,就在推送 VC 上运行这段代码:
guard UIDevice().userInterfaceIdiom == .phone else {
// fix doesn't apply to iPad, push or perform segue:
self.performSegue(withIdentifier: "mySegue", sender: self)
// navigationController?.pushViewController(destinationVC, animated: true)
return;
}
//create text field with matching settings so keyboard will look the same as its destination
let tempTextField = UITextField.init()
tempTextField.keyboardType = .default
tempTextField.keyboardAppearance = .light
tempTextField.autocorrectionType = .default
view.addSubview(tempTextField)
//show keyboard, then push VC, then remove the text field (see bottom)
//make sure destination text field calls becomeFirstResponder() in its VC's viewDidLoad()
UIView.setAnimationsEnabled(false) //set to false to disable slide up animation or true to keep it
tempTextField.becomeFirstResponder()
UIView.setAnimationsEnabled(true)
//find keyboard window
var keyboardWindow: UIWindow?
for window in UIApplication.shared.windows.reversed() {
if String(describing: type(of: window)) == "UIRemoteKeyboardWindow" {
keyboardWindow = window
break
}
}
keyboardWindow?.rootViewController?.view.isHidden = true //this prevents glitches
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0/60.0) {
// push or perform segue
self.performSegue(withIdentifier: "mySegue", sender: self)
// navigationController?.pushViewController(destinationVC, animated: true)
keyboardWindow?.rootViewController?.view.isHidden = false
//this spring animation is identical to default push slide animation
let spring = CASpringAnimation(keyPath: "position")
spring.damping = 500
spring.mass = 3
spring.initialVelocity = 0
spring.stiffness = 1000
spring.fromValue = CGPoint.init(x: self.view.frame.width, y:0) //you can enter e.g y:1000 to delay slide up animation
spring.toValue = CGPoint.init(x: 0, y:0)
spring.duration = 0.5
spring.isAdditive = true
keyboardWindow?.layer.add(spring, forKey: nil)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
tempTextField.removeFromSuperview()
}
您可以通过不禁用动画来保持向上滑动动画(上面的 becomeFirstResponder())。如果选择此选项,则可以通过将 y:0 替换为 y:1000 来延迟向上滑动动画。您可以使用此值。