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

#ios #swift

#iOS #swift

Вопрос:

Я создаю 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)
    ])
}
  

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


экран


Обновление: когда 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>>
  

Комментарии:

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

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

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

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

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

Ответ №1:

 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 .

Комментарии:

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

Ответ №2:

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

Комментарии:

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

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

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

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

5. Не могли бы вы прокомментировать комментарий?