iOS Dark Keyboard在UINavigationController推送/弹出动画期间具有背景

时间:2017-06-20 14:15:01

标签: ios uinavigationcontroller uikeyboard

在导航控制器推/动画动画期间,键盘较暗,然后处于最终状态。在动画结束时,这个黑色背景视图就消失了。轻(白色)键盘样式没有这种效果。

如何摆脱这种黑色背景?

我已经尝试将窗口颜色设置为白色并将导航控制器背景设置为白色。

视频

https://www.dropbox.com/s/z1grj821fj306th/Untitled.mov?dl=0

截图:

enter image description here

1 个答案:

答案 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 来延迟向上滑动动画。您可以使用此值。