简体   繁体   English

当用户单击UITextView并出现键盘时,如何使背景变暗/着色?

[英]How to darken/tint background when user clicks UITextView and keyboard appears?

Currently, I am able to make my keyboard appear/hide when I click inside/outside my UITextView. 当前,当我在UITextView的内部/外部单击时,我可以使键盘显示/隐藏。 I'd like to make this nicer by tinting the background darker when keyboard appears, and then have the background return to normal when keyboard goes away. 我想通过在键盘出现时将背景变暗来使背景更好,然后在键盘消失时使背景恢复正常。

I was told this behavior might be called "Focus" or "Modal Shadow Overlay" but have been unable to find a tutorial or images that match my goal. 有人告诉我这种行为可能被称为“焦点”或“模态阴影覆盖”,但找不到符合我目标的教程或图像。 Here is a screenshot that shows exactly what I want to accomplish: when writing a caption for a new Instagram post, the background tints darker. 这是一个截图 ,确切地显示了我要完成的工作:在为新的Instagram帖子撰写标题时,背景颜色变深。

  1. How do I implement this behavior in Swift? 如何在Swift中实现此行为?
  2. What's this behavior called in iOS programming? iOS编程中的这种行为是什么?

Thank you. 谢谢。 [: [:

First of all to answer your two questions : 首先回答您的两个问题:

  1. There are many ways to implement the overlay. 有很多方法可以实现覆盖。

    • You can add a UIView as a subview, giving it constraints as vertical spacing from textView and aligning the bottom of the self.view and change its alpha when keyboard is presented/dismissed. 您可以将UIView添加为子视图,为它赋予与textView垂直间距的约束,并对齐self.view的底部,并在显示/关闭键盘时更改其alpha。
    • You can add a MaskView to self.view of a viewcontroller. 您可以将MaskView添加到视图控制器的self.view中。 The problem would be that when a mask is applied it turns all the other area black(Of course you can change color) and only the part that you set in the mask frame will be the color(black with 0.5 alpha) that you suggested. 问题在于,当应用遮罩时,它会将所有其他区域变为黑色(当然您可以更改颜色),并且仅在遮罩框架中设置的部分将是您建议的颜色(带有0.5 alpha的黑色)。
  2. You can call it adding an overlay(there isn't something else other than adding a mask from Apple's documentation that I've come across) 您可以称其为添加叠加层(除了我遇到过的Apple文档中的蒙版外,没有别的东西)

Now coming to the approach I've been using for a long time. 现在介绍我已经使用了很长时间的方法。

I add a UIView called overlay variable to my ViewController, Currently setting its frame to CGRect.zero 我向我的ViewController添加了一个名为overlay变量的UIView ,当前将其框架设置为CGRect.zero

var overlay: UIView = UIView(frame: CGRect.zero)

After that, I add the Notification Observers for keyboardWillShow and keyboardWillHide in viewDidLoad. 之后,我在viewDidLoad中为keyboardWillShowkeyboardWillHide添加了通知观察器。

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

And add the corresponding selectors to handle the Notifications 并添加相应的选择器以处理通知

@objc func keyboardWillShow(notification: NSNotification)
@objc func keyboardWillHide(notification: NSNotification)

In keyboardWillShow, I get the keyboard frame to get the keyboard height 在keyboardWillShow中,我得到了键盘框架来获得键盘高度

After that, I calculate the height of the overlay by getting the height of the screen and subtracting the navigation bar height , height of the textView and any margin added to the top of textView 之后,我通过获取屏幕的高度并减去导航栏的高度textView的高度以及添加到textView顶部的任何边距来计算覆盖层的高度

Then I initialize my overlay variable by giving it the Y Position of from just below the textView. 然后,我通过从textView的正下方给出其Y位置来初始化我的overlay变量。 Initially, I set it's color to be UIColor.clear Add it as a subView to self.view and then changing it's color to black with 0.5 alpha with a 0.5 duration animation. 最初,我将其颜色设置为UIColor.clear将其作为子视图添加到self.view,然后使用0.5的alpha和0.5持续时间动画将其颜色更改为黑色

@objc func keyboardWillShow(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {


        let overlayHeight = UIScreen.main.bounds.height - heightOfNavigationBar - keyboardSize.height - textView.frame.size.height - topConstraintofTextView(if any)

        let overlayFrame = CGRect(x: 0, y: textView.frame.size.height + textView.frame.origin.y, width: UIScreen.main.bounds.width, height: overlayHeight)

        self.overlay = UIView(frame: overlayFrame)
        self.overlay.backgroundColor = .clear
        self.view.addSubview(overlay)
        UIView.animate(withDuration: 0.5, animations: {
            self.overlay.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        })

    }

}

After that, In keyboardWillHide, I change the alpha of overlay to be 0 with a little animation and as soon as it ends I remove the Overlay from superView. 之后,在keyboardWillHide中,我通过一点动画将叠加的alpha更改为0 ,并在结束时立即从superView中删除了Overlay。

@objc func keyboardWillHide(notification: NSNotification) {

        UIView.animate(withDuration: 0.5, animations: {
            self.overlay.backgroundColor = UIColor.black.withAlphaComponent(0)
        }, completion: { (completed) in
            self.overlay.removeFromSuperview()
        })
        self.overlay.removeFromSuperview()
}

And I do self.view.endEditing(true) in touchesBegan of viewController to dismiss the keyboard but that's upto you how you want to dismiss it. 我在viewController的touchesBegan中执行self.view.endEditing self.view.endEditing(true)来关闭键盘,但这取决于您如何关闭键盘。

Here's how it looks 看起来像这样

1个

Hope it helps! 希望能帮助到你!

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

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