当键盘存在时,使用UITextView向上移动UIAlertController样式

时间:2017-01-27 14:19:03

标签: ios swift keyboard uitextview uialertview

我有一个带UITextView的AlertController。

当UITexView成为第一响应者时,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()
    })
}

这是我的结果:

enter image description here 有解决方案吗?

提前致谢

5 个答案:

答案 0 :(得分:1)

默认情况下,

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

  

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

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

答案 1 :(得分:1)

只需添加文本字段,然后将其删除

    alert.addTextField { field in
        field.translatesAutoresizingMaskIntoConstraints = false
        field.heightAnchor.constraint(equalToConstant: 0).isActive = true
    }

    let inCntrlr =  alert.childViewControllers[0].view!
    inCntrlr.removeFromSuperview()

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

答案 2 :(得分:0)

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

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
    }
}

答案 3 :(得分:0)

呈现警报控制器之后。打开TextView的键盘,然后向上移动警报控制器。 我希望这会适合您。

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

答案 4 :(得分:0)

我创建了这个直接替换,当然也可以针对任何特殊需求进行定制。这很简单,而且“行之有效”!

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
}