ios - responde - sensibilidad pantalla iphone 6 plus
Reconocer el toque en el tÃtulo de la barra de navegación (7)
Con respecto a navigationItem.titleView
es una UIView
hecho, terminé usando un UIButton
que le da toda la flexibilidad fuera de la caja.
override func viewDidLoad() {
// Create title button
let titleViewButton = UIButton(type: .system)
titleViewButton.setTitleColor(UIColor.black, for: .normal)
titleViewButton.setTitle("Tap Me", for: .normal)
// Create action listener
titleViewButton.addTarget(self, action: #selector(YourViewController.titleViewButtonDidTap), for: .touchUpInside)
// Set the title view with newly created button
navigationItem.titleView = titleViewButton
}
@objc func titleViewButtonDidTap(_ sender: Any) {
print("Title did tap")
}
¿Podría alguien, por favor, ayudarme a reconocer un toque cuando un usuario toca el título en la barra de navegación ?
Me gustaría reconocer este toque y luego animar el tableHeaderView que aparece. Posiblemente deslice el TableView hacia abajo.
La idea es que el usuario pueda seleccionar una opción rápida (desde tableViewHeader) para volver a llenar la TableView.
Sin embargo no puedo reconocer ningún grifo.
Estoy usando Swift.
Gracias.
De las respuestas, podemos decir que hay dos enfoques para hacer esto.
- Adición de un
tapGestureRecognizer
al enfoquetitleView
. Este no parece elegante y requiere que toques la fuente del título de la barra de navegación, así que no lo recomendaría. - Añadiendo un método
tapGestureRecognizer
anavigationBar
. Este parece bastante elegante, pero el problema con las respuestas publicadas que toman este enfoque es que todas ellas impiden que los controles dentro de la barra de navegación funcionen. Aquí está mi implementación de este método que permite que sus controles continúen funcionando.
Swift 3
// Declare gesture recognizer
var tapGestureRecognizer: UITapGestureRecognizer!
override func viewWillAppear(_ animated: Bool) {
// Add gesture recognizer to the navigation bar when the view is about to appear
tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(self.navigationBarTapped(_:)))
self.navigationController?.navigationBar.addGestureRecognizer(tapGestureRecognizer)
// This allows controlls in the navigation bar to continue receiving touches
tapGestureRecognizer.cancelsTouchesInView = false
}
override func viewWillDisappear(_ animated: Bool) {
// Remove gesture recognizer from navigation bar when view is about to disappear
self.navigationController?.navigationBar.removeGestureRecognizer(tapGestureRecognizer)
}
// Action called when navigation bar is tapped anywhere
@objc func navigationBarTapped(_ sender: UITapGestureRecognizer){
// Make sure that a button is not tapped.
let location = sender.location(in: self.navigationController?.navigationBar)
let hitView = self.navigationController?.navigationBar.hitTest(location, with: nil)
guard !(hitView is UIControl) else { return }
// Here, we know that the user wanted to tap the navigation bar and not a control inside it
print("Navigation bar tapped")
}
ps Por favor, elimine los comentarios si este código va a entrar en producción.
Esta es una solución, aunque no super elegante. En el guión gráfico solo coloque un UIButton regular sobre el título y adjúntelo a una IBAction en su ViewController. Puede que tenga que hacer esto para cada vista.
Hay una solución más simple y elegante que utiliza reconocedores de gestos (al menos para iOS 9 y superior).
UITapGestureRecognizer * titleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(titleTapped)];
[self.navigationItem.titleView addGestureRecognizer:titleTapRecognizer];
A continuación, agregue el método del título girado:
-(void) titleTapped {
// Called when title is tapped
}
La respuesta de Bruno fue del 90% para mí. Una cosa que noté, sin embargo, fue que la funcionalidad UIBarButtonItem para el controlador de navegación dejó de funcionar en otros controladores de vista, una vez que este gestor de reconocimiento de gesto fue agregado. Para solucionar este problema, simplemente elimino el gesto del controlador de navegación cuando la vista se prepara para desaparecer:
var tapGestureRecognizer : UITapGestureRecognizer!
override func viewWillAppear(_ animated: Bool) {
tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(self.navBarTapped(_:)))
self.navigationController?.navigationBar.addGestureRecognizer(tapGestureRecognizer)
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.navigationBar.removeGestureRecognizer(tapGestureRecognizer)
}
func navBarTapped(_ theObject: AnyObject){
print("Hey there")
}
Un enfoque simple puede ser simplemente crear el reconocedor de gestos de toque y adjuntarlo al elemento de la barra de navegación.
// on viewDidLoad
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(YourViewController.somethingWasTapped(_:)))
self.navigationController?.navigationBar.addGestureRecognizer(tapGestureRecognizer)
func somethingWasTapped(_ sth: AnyObject){
print("Hey there")
}
UINavigationBar
no expone su jerarquía de vista interna. No hay una forma compatible de obtener una referencia a UILabel
que muestre el título.
Se podría subviews
en su jerarquía de vistas "manualmente" (buscando a través de sus subviews
), pero eso podría dejar de funcionar en una versión futura de iOS porque la jerarquía de vistas es privada.
Una solución alternativa es crear un UILabel
y configurarlo como el elemento de navigationItem.titleView
su controlador de UILabel
. Depende de usted para que coincida con el estilo de la etiqueta predeterminada, que puede cambiar en diferentes versiones de iOS.
Dicho esto, es bastante fácil de configurar:
override func didMove(toParentViewController parent: UIViewController?) {
super.didMove(toParentViewController: parent)
if parent != nil && self.navigationItem.titleView == nil {
initNavigationItemTitleView()
}
}
private func initNavigationItemTitleView() {
let titleView = UILabel()
titleView.text = "Hello World"
titleView.font = UIFont(name: "HelveticaNeue-Medium", size: 17)
let width = titleView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)).width
titleView.frame = CGRect(origin:CGPoint.zero, size:CGSize(width: width, height: 500))
self.navigationItem.titleView = titleView
let recognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewController.titleWasTapped))
titleView.userInteractionEnabled = true
titleView.addGestureRecognizer(recognizer)
}
@objc private func titleWasTapped() {
NSLog("Hello, titleWasTapped!")
}
Estoy configurando el tamaño de la etiqueta a su ancho natural (usando sizeThatFits:
, pero estoy configurando su altura a 500. La barra de navegación mantendrá el ancho pero reducirá la altura a la altura de la barra. Esto maximiza el área disponible para hacer tapping (ya que la altura natural de la etiqueta puede ser de solo ~ 22 puntos pero la barra tiene 44 puntos de altura).