【问题标题】:iOS Dark Keyboard has background during UINavigationController push/pop animationiOS 暗键盘在 UINavigationController 推送/弹出动画期间具有背景
【发布时间】:2017-11-23 03:27:11
【问题描述】:

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

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

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

视频:

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

屏幕截图:

【问题讨论】:

  • 您找到答案/解决方案了吗?
  • 不,我停止追逐这个,它不在客户的优先级列表中,我们朝另一个方向移动。 iOS上的键盘太糟糕了,它有自己的意识,例如有时它会在侧滑关闭时保持可见,有时它会在您从右向左滑动 VC 以关闭它时交互隐藏。

标签: ios uinavigationcontroller uikeyboard


【解决方案1】:

选项 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 来延迟上滑动画。你可以使用这个值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多