Skip to content

Instantly share code, notes, and snippets.

@unixb0y
Last active November 26, 2021 05:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save unixb0y/42a1ae0fb707bdb5e1e484bafd33d44a to your computer and use it in GitHub Desktop.
Save unixb0y/42a1ae0fb707bdb5e1e484bafd33d44a to your computer and use it in GitHub Desktop.
Drop-in UIAlertController replacement with embedded UITextView
//
// TextViewAlertController.swift
// TextViewAlertController
//
// Created by Davide Toldo on 01.11.19.
// Copyright © 2019 Davide Toldo. All rights reserved.
//
import UIKit
class TextViewAlertController: UIAlertController {
let textView: UITextView = {
let view = UITextView(frame: CGRect.zero)
view.layer.cornerRadius = 5
view.layer.masksToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
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
}
}
convenience init(title: String?) {
self.init(title: title, message: "\n\n\n\n\n\n", preferredStyle: .alert)
}
override var preferredStyle: UIAlertController.Style {
return .alert
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textView)
[textView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8),
textView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8),
textView.topAnchor.constraint(equalTo: view.topAnchor, constant: 64),
textView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -64)].forEach({ $0.isActive = true })
NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(sender:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(sender:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(sender:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textView.becomeFirstResponder()
UIView.animate(withDuration: 0.3) {
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
}
}
@unixb0y
Copy link
Author

unixb0y commented Nov 1, 2019

Usage:

let controller = TextViewAlertController(title: "Title")

let okay    = UIAlertAction(title: "Done", style: .default) { (_) in
    print("okay, this is the text:", controller.textView.text)
}
let cancel  = UIAlertAction(title: "Enod", style: .cancel) { (_) in
    print("cancel")
    controller.textView.resignFirstResponder()
}
controller.addAction(okay)
controller.addAction(cancel)

present(controller, animated: true)

@abhishekduttlikeminds
Copy link

TextViewAlertController view frame is full, is there a way to modify the frame, as apple says about private view of alertcontroller. @unixb0y

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment