Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

640
Views
El botón en UITableView tableFooterView no responde al tacto mientras la vista de tabla se ajusta después de rebotar

Tengo un UIButton en un UITableView de tableFooterView . La vista de tabla es una subvista de la vista de un UIViewController . El botón en la vista de pie de página funciona bien, excepto que si logra tocarlo demasiado rápido después de arrastrar después de la vista de tabla de modo que necesita recuperarse, el botón registra el toque (el resaltado cambia) pero la acción del botón no se llama.

Esto es una pequeña molestia para los usuarios, pero para mí el principal problema es que mis pruebas de interfaz de usuario tocan el botón demasiado pronto y luego fallan porque el siguiente paso no funciona.

Probé esto en el simulador y en un dispositivo, en mi aplicación y en una aplicación nueva y fresca. Siempre ocurre.

¿Es esto un error en iOS? De cualquier manera, ¿hay alguna solución, al menos por el bien de mis pruebas de interfaz de usuario?

Estoy usando iOS 15.

Aquí hay un código de ejemplo que reproduce el problema:

 import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let count = 20 override func viewDidLoad() { super.viewDidLoad() let tableView = UITableView() tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") tableView.delegate = self tableView.dataSource = self let button: UIView = .button(self, action: #selector(onTap)) button.frame = CGRect(origin: .zero, size: .init(width: UIView.noIntrinsicMetric, height: 200)) tableView.tableFooterView = button } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = "Row \(indexPath.row)" return cell } @objc func onTap(_ sender: UIButton) { let alert = UIAlertController(title: "Alert", message: "Message!", preferredStyle: .alert) alert.addAction(.init(title: "OK", style: .default, handler: nil)) present(alert, animated: true, completion: nil) } } extension UIView { static func button(_ target: Any?, action: Selector) -> UIView { let view = UIView() view.isUserInteractionEnabled = true let button = UIButton(type: .system) button.backgroundColor = .green button.layer.cornerRadius = 10 button.setTitle("Press Me", for: .normal) button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true button.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true button.widthAnchor.constraint(equalToConstant: 100).isActive = true button.heightAnchor.constraint(equalToConstant: 50).isActive = true button.addTarget(target, action: action, for: .touchUpInside) return view } }

Un gif que muestra el problema:

gif de la acción del botón de vista de la mesa de rebote

La parte relevante de mi prueba de interfaz de usuario:

 extension XCUIElement { func tapFooterButton() { let button = tables.buttons["Press Me"] XCTAssertTrue(button.waitForExistence(timeout: 10)) button.tap() } }

La prueba de IU no tiene problemas para encontrar el botón en el pie de página; se desplaza automáticamente hasta el botón, pero a veces intenta tocar el botón demasiado pronto y, por lo tanto, la prueba de la interfaz de usuario se atasca.

¿Quizás el toque del botón se interrumpe por el desplazamiento, como si no se registrara como un retoque en el interior porque la posición del botón se movió?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

La solución de prueba de IU que estoy probando actualmente, en caso de que alguien esté interesado, es llamar a tap() en el elemento del botón nuevamente (primero verificando isHittable ) en caso de que no haya funcionado la primera vez. No es ideal pero si funciona, es algo al menos.

over 4 years ago · Santiago Trujillo Report

0

Estaba revisando algunas aplicaciones de Apple iOS y parece que este es el comportamiento normal que pretendían desde el punto de vista de UX.

No pude encontrar muchas preguntas similares, sin embargo, encontré esto que parece bastante cercano a lo que desea, sin embargo, lamentablemente el enlace publicado en la respuesta ya no existe.

Un comentario de esa respuesta explica este comportamiento:

UIScrollView retrasa el envío de eventos táctiles hasta que sepa si esos toques no son eventos de desplazamiento. Su problema es que un usuario que toca es un evento de desplazamiento cuando UIScrollView se está moviendo.

Con eso en mente, aquí hay una solución alternativa que podría funcionar, sin embargo, solo debe usarse para probar/depurar, ya que podría evitar que se complete el rebote.

Aquí está mi proceso de pensamiento

  1. UITableView es una subclase de UIScrollView que tiene sus propios reconocedores de gestos
  2. Cree una subclase UITableView que se ajuste a UIGestureRecognizerDelegate
  3. Implemente el gestureRecognizer shouldRecognizeSimultaneouslyWith con para obtener el toque.
  4. Comprobar si el toque fue en el botón
  5. Presiona el botón programáticamente
  6. Use esta vista de tabla personalizada al inicializar su vista de tabla
 class CustomTableView: UITableView, UIGestureRecognizerDelegate { func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { // DO THE FOLLOWING ONLY IN DEBUG - IFDEF DEBUG // Get the tap location let tapLocation = gestureRecognizer.location(in: self) // Check if the button was tapped if let button = hitTest(tapLocation, with: nil) as? UIButton { // Programmatically perform the button tap // This might stop the bounce currently on the main thread button.sendActions(for: .touchUpInside) } // ENDIF return true } }

Luego se usa normalmente

 let tableView = CustomTableView()
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!