import Foundation
import UIKit
class ScrollViewController: UIViewController {
private var notifs: [Any?] = []
private lazy var navController: UINavigationController = {
let navVC = UINavigationController(rootViewController: self)
navVC.navigationBar.barTintColor = UIColor.lightGray
navVC.navigationBar.tintColor = UIColor.white
return navVC
}()
private lazy var scrollView: UIScrollView = {
let sv = UIScrollView()
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
private lazy var contentView: UIView = {
let cv = UIView()
cv.translatesAutoresizingMaskIntoConstraints = false
return cv
}()
private lazy var titleText: UITextField = {
let field = UITextField()
field.translatesAutoresizingMaskIntoConstraints = false
field.borderStyle = UITextField.BorderStyle.roundedRect
field.placeholder = "Title"
return field
}()
private lazy var body: UITextView = {
let field = UITextView(frame: CGRect.zero)
field.translatesAutoresizingMaskIntoConstraints = false
addTextViewBorder(field)
return field
}()
let labelTwo: UILabel = {
let label = UILabel()
label.text = "Scroll Bottom"
label.backgroundColor = .green
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
var keyboardHeight: CGFloat = 0.0
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
initUI()
addConstraints()
initEvents()
}
func getNavigationController() -> UINavigationController {
return navController
}
func addTextViewBorder(_ textView: UITextView) {
textView.layer.borderColor = UIColor.gray.cgColor
textView.layer.borderWidth = 1.0
textView.layer.cornerRadius = 5.0
}
func initUI() {
view.backgroundColor = UIColor.white
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelDidTap))
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(saveDidTap))
self.view.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.addSubview(titleText)
contentView.addSubview(body)
body.delegate = self
body.isScrollEnabled = false
scrollView.isScrollEnabled = true
scrollView.isUserInteractionEnabled = true
scrollView.contentSize = CGSize(width: 400, height: 2300)
}
func addConstraints() {
// scroll view
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8.0),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8.0),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0)
])
// content view
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 1.0)
])
// title text field
NSLayoutConstraint.activate([
titleText.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
titleText.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
titleText.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0),
titleText.heightAnchor.constraint(equalToConstant: 31)
])
// body text view
NSLayoutConstraint.activate([
body.topAnchor.constraint(equalTo: titleText.bottomAnchor, constant: 8.0),
body.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
body.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0),
body.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0),
body.heightAnchor.constraint(equalToConstant: 200)
])
}
func initEvents() {
let tap = UITapGestureRecognizer(target: self, action: #selector(viewDidTap(recognizer:)))
self.view.addGestureRecognizer(tap)
// Keyboard events
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notif:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notif:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
// MARK: - Selector
@objc func cancelDidTap() {
self.dismiss(animated: true, completion: nil)
}
@objc func saveDidTap() {
}
@objc func viewDidTap(recognizer: UITapGestureRecognizer) {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
@objc func keyboardWillShow(notif: Notification) {
if let userInfo = notif.userInfo, let keyboardSize = userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue {
let kbHeight = keyboardSize.cgRectValue.height
keyboardHeight = kbHeight
// let bkgndRect = poemBody.superview!.frame
// poemBody.superview?.frame(forAlignmentRect: bkgndRect)
// scrollView.setContentOffset(CGPoint(x: 0.0, y: poemBody.frame.origin.y - keyboardHeight), animated: true)
}
}
@objc func keyboardWillHide(notif: Notification) {
let contentInset = UIEdgeInsets.zero
scrollView.contentInset = contentInset
scrollView.scrollIndicatorInsets = contentInset
}
}
extension ScrollViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let fixedWidth = textView.frame.size.width
var newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
if newSize.height < 200 {
newSize.height = 200
}
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
if let constraint = (body.constraints.filter { $0.firstAttribute == .height }.first) {
constraint.constant = newSize.height
}
textView.layoutIfNeeded()
}
}
Используйте этот код, ваша проблема будет решена.Основная проблема с вашим кодом - привязка contentView , и вы выдавали текстовое поле заголовка bottomAnchor к body.topAnchor, которое вызывает высоту вашего основного текста .