Невидимая кнопка не реагирует на нажатие

#ios #swift #uitableview #uibutton

#iOS #swift #uitableview #uibutton

Вопрос:

Я пытаюсь поместить невидимую кнопку поверх imageview, потому что imageview слишком мал, чтобы реагировать на распознаватель жестов касания. Я не могу просто увеличить изображение, потому что оно выглядит плохо. Вот код для imageview для увеличения количества:

 private func configureIncreaseQuantityImageView() {
    increaseQuantityImageView.contentMode = .scaleAspectFill
    increaseQuantityImageView.image = UIImage(named: "arr_up")
    //increaseQuantityImageView.isUserInteractionEnabled = true
    //increaseQuantityImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleIncreaseQuantityTapped)))
    contentView.addSubview(increaseQuantityImageView)
    increaseQuantityImageView.translatesAutoresizingMaskIntoConstraints = false
    increaseQuantityImageView.centerYAnchor.constraint(equalTo: verticalDivider.centerYAnchor).isActive = true
    increaseQuantityImageView.leftAnchor.constraint(equalTo: verticalDivider.rightAnchor, constant: 12).isActive = true
    increaseQuantityImageView.widthAnchor.constraint(equalToConstant: 12).isActive = true
    increaseQuantityImageView.heightAnchor.constraint(equalToConstant: 8).isActive = true
}
  

Вот код для невидимой кнопки, которая не реагирует на прикосновение:

 private func configureInvisibleIncreaseQuantityButton() {
    invisibleIncreaseQuantityButton.backgroundColor = .clear
    invisibleIncreaseQuantityButton.addTarget(self, action: #selector(handleIncreaseQuantityTapped), for: .touchUpInside)
    contentView.addSubview(invisibleIncreaseQuantityButton)
    invisibleIncreaseQuantityButton.translatesAutoresizingMaskIntoConstraints = false
    invisibleIncreaseQuantityButton.centerYAnchor.constraint(equalTo: verticalDivider.centerYAnchor).isActive = true
    invisibleIncreaseQuantityButton.leftAnchor.constraint(equalTo: verticalDivider.rightAnchor).isActive = true
    invisibleIncreaseQuantityButton.widthAnchor.constraint(equalToConstant: 35).isActive = true
    invisibleIncreaseQuantityButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
}
  

Вот функция, которая не вызывается при нажатии на невидимую кнопку. Я сделал что-то очень похожее для кнопки уменьшения количества, поэтому нет необходимости показывать этот код.

 @objc private func handleIncreaseQuantityTapped() {
    self.quantity  = 1
    quantityValueLabel.text = "(self.quantity)"
    self.menuItem?.quantity = self.quantity
    guard let item = self.menuItem else { return }
    delegate?.updateMenuItem(item)
}
  

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

1. Невидимые виды не регистрируют касания.

2. Если изображение слишком мало для регистрации нажатий, то у вас все равно может возникнуть проблема с доступностью / удобством использования. Может быть, вы могли бы использовать a, UIButton но изменить contentInsets так, чтобы кнопка была больше изображения?

Ответ №1:

Swift 4.2

Вы можете добавить ее UITapGestureRecognizer в свой imageView супервизор и задать диапазон, содержащий imageView местоположение.

Например:

 let superviewOfImageView = UIView()
let imageView = UIImageView()

func setupTapGesture() {
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
    superviewOfImageView.addGestureRecognizer(tapGesture)
}

@objc func didTap(_ gesture: UITapGestureRecognizer) {
    // user's finger tap at superview's location.
    let point = gesture.location(in: superviewOfImageView)

    // set the range you want.
    let width = superviewOfImageView.frame.width/4 
    let height = superviewOfImageView.frame.height/4
    let boundaryOfImageView = CGRect(x: 0, y: 0, width: width, height: height)

    // if in the range you set, do what ever you want.
    if boundaryOfImageView.contains(point) {
        // do something here.
    }
}
  

Удачи, мой друг!

Ответ №2:

Вообще говоря, вам не нужна кнопка для этого. Вы можете выполнить то же самое, просто используя UIView, который накладывается поверх объекта.

Но при выполнении этого программно есть несколько соображений, в основном, из-за того, что вы фактически визуально не видите, где расположен объект пользовательского интерфейса, из-за того, что все это обрабатывается в коде вместо раскадровки.

Мои предложения: 1) Взаимодействие с пользователем может быть не включено в вашем представлении increaseQuantityImageView.isUserInteractionEnabled = true

2) Представление, с которым вы пытаетесь взаимодействовать, скрыто за другим представлением в иерархии вложенных представлений

.addSubview() Функция может заключаться в размещении объекта, к которому вы хотите прикоснуться, под объектом, который она должна прикрывать.

Вот отличный небольшой фрагмент, который я часто использую, чтобы действительно быстро найти вложенный просмотр:

Эта функция возвращает все вложенные представления, содержащиеся в предоставленном представлении, в виде массива.

 private func getSubviewsOf<T : UIView>(view:UIView) -> [T] {
        var subviews = [T]()

        for subview in view.subviews {
            subviews  = getSubviewsOf(view: subview) as [T]

            if let subview = subview as? T {
                subviews.append(subview)
            }
        }
        return subviews
    }
  

Вы можете использовать ее следующим образом:

 // First, let's get an ID on the object you are trying to find
`invisibleDecreaseQuantityButton.restorationIdentifier = "targetView"`

// Then, also set a restoration ID on the view that this targetView is supposed to be on top of
increaseQuantityImageView.restorationIdentifier = "coveredView"

// Now, get all of the subviews of the main view
let subviews = self.getSubViewsOf(view: self.view)

var targetViewIndex = 0
var coveredViewIndex = 0
// Figure out which view is the correct one
for (index, view) in subviews.enumerated() {

    // When we find the target view
    if view.restorationIdentifier == "targetView" {
        // Let's print it so we know where it resides
        print("targetView's index: (index)")
        targetViewIndex = index
    }

    if view.restorationIdentifier == "coveredView"{
        // print this one too
        print("coveredView's index: (index)")
        coveredViewIndex = index
    }
}

  

На самом деле эта часть предназначена только для того, чтобы помочь вам в программной отладке. Если вы хотите внедрить в свое приложение более наглядный метод отладки, я бы настоятельно рекомендовал FLEX. С помощью этой платформы вы можете визуально коснуться каждого элемента и получить имя его переменной, а также визуально увидеть график с размещением всей вашей иерархии представлений в контроллере представления.

Помните, что в иерархии представлений представление с более низким индексом в массиве вложенных представлений означает, что оно ближе к началу представления. Итак:

 if targetIndex > coveredViewIndex {
    // push the coveredView behind the targetView
    self.view.insertSubview(targetView, at: coveredViewIndex)
}
  

Подробнее об иерархиях здесь, в документации Apple

Спасибо, если я могу помочь вам в дальнейшей отладке. Вот небольшой скриншот FLEX, который я только что сделал, это отличный инструмент: