繁体   English   中英

iOS 深色键盘在 UINavigationController 推送/弹出动画期间具有背景

[英]iOS Dark Keyboard has background during UINavigationController push/pop animation

在导航控制器推送/弹出动画期间,键盘比其最终状态更暗。 在动画结束时,这个黑色背景视图消失了。 浅色(白色)键盘风格没有这种效果。

我怎样才能摆脱这种黑色背景?

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

视频:

https://www.dropbox.com/s/z1grj821fj306th/Untitled.mov?dl=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 来延迟向上滑动动画。 你可以玩这个值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM