【问题标题】:move up UIAlertController style Alert with UITextView when keyboard is present当键盘存在时,使用 UITextView 向上移动 UIAlertController 样式警报
【发布时间】:2017-06-13 06:13:51
【问题描述】:

我有一个带有 UITextView 的 AlertController。

当 UIExView 成为第一响应者时,alter 不会随着键盘向上移动。

这是我的代码:

@IBAction func showAlert(sender: AnyObject) {

    let alertController = UIAlertController(title: "Hello, I'm alert! \n\n\n\n\n\n\n", message: "", preferredStyle: .alert)

    let rect        =   CGRect(x: 15, y: 15, width: 240, height: 150)//CGRectMake(15, 50, 240, 150.0)
    let textView    = UITextView(frame: rect)

    textView.font               = UIFont(name: "Helvetica", size: 15)
    textView.textColor          = UIColor.lightGray
    textView.backgroundColor    = UIColor.white
    textView.layer.borderColor  = UIColor.lightGray.cgColor
    textView.layer.borderWidth  = 1.0
    textView.text               = "Enter message here"
    textView.delegate           = self

    alertController.view.addSubview(textView)

    let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let action = UIAlertAction(title: "Ok", style: .default, handler: { action in

        let msg = (textView.textColor == UIColor.lightGray) ? "" : textView.text

        print(msg!)

    })
    alertController.addAction(cancel)
    alertController.addAction(action)


    self.present(alertController, animated: true, completion: {

        textView.becomeFirstResponder()
    })
}

这是我的结果:

有解决办法吗?

提前致谢

【问题讨论】:

    标签: ios swift keyboard uitextview uialertview


    【解决方案1】:

    UIAlertController 默认会在显示键盘时向上滑动。这里的问题是您已经向警报控制器添加了一个子视图。来自UIAlertController docs

    UIAlertController 类旨在按原样使用,而不是 支持子类化。此类的视图层次结构是私有的,并且 不得修改。

    将您自己的子视图添加到警报中违背了文档所说的内容,并且很可能是导致您的问题的原因。如果您需要包含文本视图的警报,最好的办法是创建自己的视图并自行管理。

    【讨论】:

    • @keithbhunter 是对的。或者,您可以使用func addTextField(configurationHandler: ((UITextField) -> Void)? = nil) 的文本字段。那个由 UIAlertViewController 管理。
    【解决方案2】:

    只需添加TextField,然后将其删除

        alert.addTextField { field in
            field.translatesAutoresizingMaskIntoConstraints = false
            field.heightAnchor.constraint(equalToConstant: 0).isActive = true
        }
    
        let inCntrlr =  alert.childViewControllers[0].view!
        inCntrlr.removeFromSuperview()
    

    然后您可以添加自己的视图。这里有一个 result

    【讨论】:

    • 在 4.2 上完美运行。非常容易实现。
    • 这确实缺乏更多信息:/请提供完整的示例。
    • 编辑:这可行,但由于某种原因,您必须在添加所有视图后将其放在警报控制器构造的末尾。一开始就为我做这件事导致应用程序崩溃。
    • 这行得通,但很高兴知道它为什么行得通:)
    【解决方案3】:

    就像。您打开键盘并更改警报位置。

    var alertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.alert)
    var alertControllerPositon:CGFloat = 0
    override func viewDidLoad() {
        super.viewDidLoad()
    
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    @IBAction func showAlert(sender: AnyObject) {
    
    let alertController = UIAlertController(title: "Hello, I'm alert! \n\n\n\n\n\n\n", message: "", preferredStyle: .alert)
    
    let rect        =   CGRect(x: 15, y: 15, width: 240, height: 150)//CGRectMake(15, 50, 240, 150.0)
    let textView    = UITextView(frame: rect)
    
    textView.font               = UIFont(name: "Helvetica", size: 15)
    textView.textColor          = UIColor.lightGray
    textView.backgroundColor    = UIColor.white
    textView.layer.borderColor  = UIColor.lightGray.cgColor
    textView.layer.borderWidth  = 1.0
    textView.text               = "Enter message here"
    textView.delegate           = self
    
    alertController.view.addSubview(textView)
    
    let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let action = UIAlertAction(title: "Ok", style: .default, handler: { action in
    
        let msg = (textView.textColor == UIColor.lightGray) ? "" : textView.text
    
        print(msg!)
    
    })
    alertController.addAction(cancel)
    alertController.addAction(action)
    
    
    self.present(alertController, animated: true, completion: {
    
        textView.becomeFirstResponder()
    })
    alertControllerPositon = alertController.view.frame.origin.y
    }
    
    @objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            alertControllerPositon = alertController.view.frame.origin.y
            let result = self.view.frame.height - (alertController.view.frame.height + alertController.view.frame.origin.y) - 20
            self.alertController.view.frame.origin.y -= (keyboardSize.height - result)
        }
    }
    
    @objc func keyboardWillHide(notification: NSNotification) {
        if self.alertController.view.frame.origin.y != alertControllerPositon  {
            self.alertController.view.frame.origin.y = alertControllerPositon
        }
    }
    

    【讨论】:

      【解决方案4】:

      在呈现警报控制器之后。打开 TextView 的键盘并向上移动警报控制器。 我希望这适合你。

      self.present(alertController, animated: true, completion: {
          textView.becomeFirstResponder()
          UIView.animate(withDuration: 0.5, animations: {
              alertController.view.frame.origin.y = 100
          })
      })
      

      【讨论】:

        【解决方案5】:

        我创建了这个插入式替代品,当然也可以根据任何特殊需求进行定制。这很简单,而且“有效”!

        https://gist.github.com/unixb0y/42a1ae0fb707bdb5e1e484bafd33d44a

        它是UIAlertController的子类,里面有一个UITextView

        当它初始化时,它会观察键盘的变化并相应地调整它的view.frame.origin.y

        var keyboardHeight: CGFloat = 100 {
            didSet {
                let height = UIScreen.main.bounds.height
                let menu = self.view.frame.height
                let keyb = self.keyboardHeight
                self.view.frame.origin.y = height-menu-keyb-20
            }
        }
        
        ...
        ...
        ...
        
        @objc func keyboardChange(sender: Notification) {
            guard let userInfo = sender.userInfo else { return }
            let endFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
            keyboardHeight = endFrame?.height ?? 100
        }
        

        【讨论】:

        • 这很好用,虽然方向改变了一点。
        猜你喜欢
        • 2013-08-15
        • 1970-01-01
        • 2018-01-12
        • 2021-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-17
        • 2010-11-10
        相关资源
        最近更新 更多