UITextField не отвечает на нажатие в пользовательском интерфейсе, созданном программно

Я создаю ViewController программно. Я добавил представление прокрутки, представление содержимого и текстовое поле с ограничениями. Пользовательский интерфейс отображается правильно. Но когда я нажимаю на текстовое поле, ничего не происходит.

override func viewDidLoad() {
    initUI()
}

func initUI() {
    scrollView = UIScrollView()
    scrollView!.translatesAutoresizingMaskIntoConstraints = false
    scrollView!.isUserInteractionEnabled = true
    view.addSubview(scrollView!)

    contentView = UIView()
    contentView!.translatesAutoresizingMaskIntoConstraints = false
    contentView!.isUserInteractionEnabled = true
    contentView!.isMultipleTouchEnabled = true
    scrollView!.addSubview(contentView!)

    titleText = UITextField(frame: CGRect.zero)
    titleText!.translatesAutoresizingMaskIntoConstraints = false
    titleText!.borderStyle = .roundedRect
    titleText!.isEnabled = true
    titleText!.isUserInteractionEnabled = true
    titleText!.placeholder = Constants.Messages.titlePlaceholder
    titleText!.delegate = self
    contentView!.addSubview(titleText!)

    // scroll view
    NSLayoutConstraint.activate([
        scrollView!.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
        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)
    ])
    // title text field
    NSLayoutConstraint.activate([
        titleText!.topAnchor.constraint(equalTo: scrollView!.topAnchor, constant: 20.0),
        titleText!.leadingAnchor.constraint(equalTo: scrollView!.leadingAnchor, constant: 8.0),
        titleText!.trailingAnchor.constraint(equalTo: scrollView!.trailingAnchor, constant: -8.0)
    ])
}

Как заставить текстовое поле реагировать на тап?


UITextField не отвечает на нажатие в пользовательском интерфейсе, созданном программно


Обновлять: Когда titleText ограничено scrollView, я получаю:

 Optional<Any>
  - some : <UIView: 0x7f84496c8550; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x600003a2cc40>>
   | <UIScrollView: 0x7f8445834400; frame = (0 0; 0 0); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600003320510>; layer = <CALayer: 0x600003a082e0>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}>
   |    | <UIView: 0x7f8449759610; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x600003a085e0>>
   |    |    | <UITextField: 0x7f8445863a00; frame = (0 0; 0 0); text = ''; opaque = NO; layer = <CALayer: 0x600003a08520>>
   |    |    |    | <_UITextFieldRoundedRectBackgroundViewNeue: 0x7f844976e740; frame = (0 0; 0 0); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x600003a087a0>>
   |    |    |    | <_UITextFieldContentView: 0x7f8449777fa0; frame = (0 0; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <__UITextTiledLayer: 0x6000018e8f60>>

Когда titleText ограничено contentView, я получаю:

Optional<Any>
  - some : <UIView: 0x7fadabcc42e0; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x6000035f9e40>>
   | <UIScrollView: 0x7fadad123800; frame = (0 0; 0 0); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600003c661f0>; layer = <CALayer: 0x6000035f86c0>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}>
   |    | <UIView: 0x7fadabcfbcf0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x6000035f9ce0>>
   |    |    | <UITextField: 0x7fadad0f6000; frame = (0 0; 0 0); text = ''; opaque = NO; layer = <CALayer: 0x6000035fa320>>
   |    |    |    | <_UITextFieldRoundedRectBackgroundViewNeue: 0x7fadabf07840; frame = (0 0; 0 0); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x6000035f8a20>>
   |    |    |    | <_UITextFieldContentView: 0x7fadabcdeaf0; frame = (0 0; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <__UITextTiledLayer: 0x6000017c4f60>>

О боже, все эти ! заставляют мои глаза гореть... Пожалуйста, избегайте их ради вашего же блага.

LinusGeffarth 09.04.2019 10:39

Можете ли вы добавить скриншот полученного пользовательского интерфейса?

LinusGeffarth 09.04.2019 10:40

А вы пробовали contentView!.isUserInteractionEnabled = false и contentView!.isMultipleTouchEnabled = false? Вам не нужно взаимодействовать с contentView, только с scrollView и textView

regina_fallangi 09.04.2019 10:42

@LinusGeffarth Я добавил скриншот. Лучше ли использовать guard let, чтобы развернуть необязательный здесь? Я думал, что это будут дополнительные утверждения.

johndoe 09.04.2019 10:45

@regina_fallangi Да, это не работает.

johndoe 09.04.2019 10:46

Спасибо. Что касается опций: большинство из них даже не нужно разворачивать. Просто замените все ! на ? и посмотрите, на что компилятор жалуется. Вы также можете создать текстовое поле следующим образом: var textField: UITextField = { /* all the code in here */ } и тогда оно не обязательно должно быть необязательным.

LinusGeffarth 09.04.2019 10:47

@LinusGeffarth, я бы порекомендовал сделать переменные lazy, поскольку они являются элементами пользовательского интерфейса.

Rakesha Shastri 09.04.2019 10:49

@RakeshaShastri даже лучше.

LinusGeffarth 09.04.2019 10:49

Проверьте иерархию представления текстового поля. Один из его родителей будет иметь высоту 0. Существует метод отладки для печати иерархии UIView.

Warren Burton 09.04.2019 10:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
180
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
import UIKit

class TestController: UIViewController, UITextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        initUI()
    }

    func initUI() {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.isUserInteractionEnabled = true
        view.addSubview(scrollView)

        let contentView = UIView()
        contentView.translatesAutoresizingMaskIntoConstraints = false
        contentView.isUserInteractionEnabled = true
        contentView.isMultipleTouchEnabled = true
        scrollView.addSubview(contentView)

        let titleText = UITextField(frame: CGRect.zero)
        titleText.translatesAutoresizingMaskIntoConstraints = false
        titleText.borderStyle = .roundedRect
        titleText.isEnabled = true
        titleText.isUserInteractionEnabled = true
        titleText.placeholder = "Constants.Messages.titlePlaceholder"
        titleText.isUserInteractionEnabled = true
        titleText.delegate = self
        contentView.addSubview(titleText)

        // scroll view
        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
            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)
            ])
        // title text field
        NSLayoutConstraint.activate([
            titleText.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20.0),
            titleText.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
            titleText.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0),
            titleText.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0)
            ])
    }
}

Попробуйте этот код, он будет работать для вас. Я протестировал ваш код и не использую принудительную распаковку при выполнении программных действий.

Проблема с вашим кодом заключается в том, что вы должны использовать нижнюю привязку при использовании UIScrollView, и вы помещаете «Текстовое поле заголовка в ScrollView» вместо того, чтобы вставлять ScrollView, вы должны привязываться к contentView.

Спасибо. Это решает проблему, используя только ограничения макета вместо использования позиционирования на основе фрейма.

johndoe 09.04.2019 12:01
func initUI() {

    let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(scrollView)

    let contentView = UIView(frame: CGRect(x: 0, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height))
    contentView.backgroundColor = UIColor.red
    scrollView.addSubview(contentView)


    let titleText =  UITextField(frame: CGRect(x: 20, y: 100, width: 300, height: 40))
    titleText.placeholder = "Enter text here"
    titleText.font = UIFont.systemFont(ofSize: 15)
    titleText.borderStyle = UITextField.BorderStyle.roundedRect
    titleText.autocorrectionType = UITextAutocorrectionType.no
    titleText.keyboardType = UIKeyboardType.default
    titleText.returnKeyType = UIReturnKeyType.done
    titleText.clearButtonMode = UITextField.ViewMode.whileEditing
    titleText.contentVerticalAlignment = UIControl.ContentVerticalAlignment.center
    titleText.delegate = self
    contentView.addSubview(titleText)



    // scroll view
    NSLayoutConstraint.activate([
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
        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)
        ])

    // title text field
    NSLayoutConstraint.activate([
        titleText.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20.0),
        titleText.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 8.0),
        titleText.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -8.0)
        ])
}

@jsloop Просто замените представление прокрутки и объявление contentView моим кодом.

Bhavesh Nayi 09.04.2019 11:16

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

Bhavesh Nayi 09.04.2019 11:24

Ваш код работает. Спасибо! Скажите, почему вы не поставили contentView.translatesAutoresizingMaskIntoConstraints = false? Если я уберу эту строку, она сработает. Разве это не требуется для представления с ограничениями, добавленными программно?

johndoe 09.04.2019 11:40

Пожалуйста, примите мой ответ. Таким образом, соответствующий пользователь может легко найти

Bhavesh Nayi 09.04.2019 11:46

Не могли бы вы обратиться к комментарию?

johndoe 09.04.2019 11:47

Не требуется для translatesAutoresizingMaskIntoConstraints

Bhavesh Nayi 09.04.2019 11:48

я знаю бро. Спасибо

Bhavesh Nayi 09.04.2019 12:23

Другие вопросы по теме