Я пытаюсь создать пользовательский интерфейс программно, но представление прокрутки и представление текста не работает должным образом - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть UIViewController с представлением прокрутки, представлением содержимого с полями, добавленными в него программно.Просмотр текста отключен.По мере ввода пользователем текстовое представление увеличивается в размерах, но не перемещается над клавиатурой.Также прокрутка не прокручивает правильное представление.Пожалуйста, проверьте прикрепленный проект .

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

Код ограничения:

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: view.topAnchor),
            contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            contentView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0)
            ])
        // title text field
        NSLayoutConstraint.activate([
            titleText.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 100),
            titleText.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
            titleText.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0),
            titleText.bottomAnchor.constraint(equalTo: body.topAnchor, 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: -40),
            body.heightAnchor.constraint(equalToConstant: 200)
        ])
    }

enter image description here

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019
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, которое вызывает высоту вашего основного текста .

0 голосов
/ 10 апреля 2019

Пожалуйста, используйте ниже код

GrowingTextView

Согласно вашему требованию textview недостаточно. Пожалуйста, попробуйте и дайте мне знать, если вы обнаружите какие-либо проблемы.

...