UITapGesture не работает даже с включенным isUserInteraction, установленным в true

#ios #swift #uikit

#iOS #swift #уикит #uikit

Вопрос:

Хорошо, вот моя ситуация:

  • Приложение для чата, у которого есть пользовательский inputAccessoryView (разумеется, отмененный)
  • Необходимо реализовать функцию ответа в чате (как в WhatsApp, где пользователь может отвечать на отдельные чаты)
  • Я показываю новый вид, keyBoardReplyView , который представляет собой короткий фрагмент чата, на который я отвечаю поверх inputAccessoryView (добавляя это программно, используя автоматическую компоновку)
  • Этот новый вид keyBoardReplyView содержит вид изображения со значком закрытия
  • Когда я нажимаю на этот значок закрытия, я хочу удалить KeyboardReplyView , но, к сожалению, жест касания, похоже, не срабатывает

Примечание: я isUserInteractionEnabled установил значение true

Что я пробовал: я прочитал в сообщении stack, что я должен установить для взаимодействия с пользователем родительского представления значение true, и я тоже попробовал это, но все равно не работает

Код того, как я добавляю свой KeyboardReplyView поверх inputAccessoryView:

 let keyboardReplyView = KeyboardSupplementaryReplyView()
    
    fileprivate func setupReplyViewForKeyboard(withTitleColor: UIColor){
        keyboardReplyView.titleLabel.textColor = withTitleColor
        keyboardReplyView.isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleReplyMessageClose))
        keyboardReplyView.closeImageView.addGestureRecognizer(tapGesture)
        inputAccessoryView?.addSubview(keyboardReplyView)
        keyboardReplyView.anchor(top: nil, leading: inputAccessoryView?.leadingAnchor, bottom: inputAccessoryView?.topAnchor, trailing: inputAccessoryView?.trailingAnchor, size: .init(width: 0, height: 60))
    }

  

Вот код для представления:

 class KeyboardSupplementaryReplyView: UIView {
    let closeImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFit
        iv.isUserInteractionEnabled = true
        iv.tintColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
        let boldConfig = UIImage.SymbolConfiguration(weight: .bold)
        let boldBell = UIImage(systemName: "xmark.circle", withConfiguration: boldConfig)
        iv.image = boldBell
        return iv
    }()
    
    let titleLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 1
        label.font = .systemFont(ofSize: 14, weight: .bold)
        return label
    }()
    
    let messageLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 2
        label.font = .systemFont(ofSize: 12)
        return label
    }()
        
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    private func setupViews(){
        let visualEffectView = UIVisualEffectView()
        visualEffectView.effect = UIBlurEffect(style: .systemMaterialDark)
        addSubview(visualEffectView)
        visualEffectView.anchor(top: topAnchor, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor)
                
        addSubview(closeImageView)
        closeImageView.anchor(top: nil, leading: nil, bottom: nil, trailing: trailingAnchor, padding: .init(top: 0, left: 0, bottom: 0, right: 4), size: .init(width: 30, height: 30))
        closeImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        
        //38
        addSubview(titleLabel)
        titleLabel.text = "Name of user replying to"
        titleLabel.anchor(top: topAnchor, leading: leadingAnchor, bottom: nil, trailing: closeImageView.leadingAnchor, padding: .init(top: 4, left: 4, bottom: 0, right: 4))
    
        addSubview(messageLabel)
        messageLabel.textColor = UIColor.white.withAlphaComponent(0.7)
        messageLabel.text = "This is a long text that is used to test of the view can hold this in the accurate and the right format let us try it out as much as we can"
        messageLabel.anchor(top: titleLabel.bottomAnchor, leading: leadingAnchor, bottom: nil, trailing: closeImageView.leadingAnchor, padding: .init(top: 2, left: 4, bottom: 0, right: 4))
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
  

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

1. Я замечаю, что вы добавили ImageView, titleLabel и messageLabel в качестве вложенных представлений, даже если у вас есть UIVisualEffectView, охватывающий весь UIView. Вы пробовали добавлять ImageView, titleLabel и messageLabel в качестве вложенных представлений UIVisualEffectView? Другим местом для поиска может быть иерархия представлений? Вы можете посмотреть, может ли быть другой вид, препятствующий жесту касания.

2. @rohanphadte Да, что касается вашего первого пункта, не думайте, что это так, потому что просмотры добавляются в порядке живой очереди друг над другом. Ваша точка зрения иерархии представлений может быть правильной, потому что я добавляю это представление поверх представления входных аксессуаров. Так что технически он перемещается с клавиатуры. Это текущий вид иерархии -> CollectionView -> Пользовательский ввод accessoryView -> Наконец, дополнительный вид клавиатуры, привязанный к верхней части пользовательского ввода вспомогательного вида. Но все же я не понимаю, почему это не сработает

3. @rohanphadte Я узнал, в чем проблема, я думаю. Поэтому, когда я добавляю этот дополнительный вид клавиатуры, я добавляю его в качестве подвида моего пользовательского вспомогательного вида ввода и привязываю его к верхней части. Очевидно, что, несмотря на то, что отображается представление supp, его область касания находится за пределами. Поэтому мне нужно добавить его в качестве подвида к самому основному представлению. Но как я могу подключить его к представлению входных аксессуаров, потому что xcode выдает ошибку «потому что у них нет общего предка. Ссылается ли ограничение или его якоря на элементы в разных иерархиях представлений? Это незаконно».