Reproducir el sonido de clic del keyboard en un controller de vista de colección

Creé una subclass de un UICollectionViewController que se utiliza como inputAccessoryViewController personalizado en una UITextView . https://developer.apple.com/reference/uikit/uiresponder/1621124-inputaccessoryviewcontroller

Quiero tocar el sonido de clic del keyboard cuando tocas una celda en la vista de colección usando playInputClick. https://developer.apple.com/reference/uikit/uidevice/1620050-playinputclick

No puedo entender cómo hacer que esto funcione en una vista de colección. Funciona para una vista simple como esta usando la propiedad inputAccessoryView de un UITextView pero no estoy seguro de qué vista de la subclass en la jerarquía del controller de la vista de colección para que el keyboard click el sonido para reproducir.

 @interface KeyboardClickView : UIView <UIInputViewAudioFeedback> @end @implementation KeyboardClickView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if(self) { UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; [self addGestureRecognizer:tap]; } return self; } - (void)tap:(id)sender { [[UIDevice currentDevice] playInputClick]; } - (BOOL)enableInputClicksWhenVisible { return YES; } @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _inputAccessoryView = [[KeyboardClickView alloc] initWithFrame:CGRectMake(0, 0, 0, 50)]; _inputAccessoryView.backgroundColor = [UIColor networkingColor]; [[UITextView appearance] setInputAccessoryView:_inputAccessoryView]; // ... } @end 

También estoy consciente de que puedes reproducir el sonido de clic del keyboard con AudioServicesPlaySystemSound(1104) pero esto no respeta la configuration del usuario si tienen los sonidos de clic del keyboard deshabilitados.

En lugar de utilizar un UICollectionViewController , defina KeyboardClickView como una subclass de UICollectionView y colóquelo en un UIViewController .

 @interface KeyboardClickView : UICollectionView <UIInputViewAudioFeedback> - (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { self = [super initWithFrame:frame collectionViewLayout:layout]; // existing implementation 

El nuevo controller de vista podría verse algo como esto:

 @interface KeyboardClickViewController: UIViewController <UICollectionViewDelegate, UICollectionViewDataSource> @property (nonatomic, strong) KeyboardClickView *clickView; @end @implementation KeyboardClickViewController -(void)viewDidLoad { [super viewDidLoad]; self.clickView = [[KeyboardClickView alloc] initWithFrame:self.view.bounds collectionViewLayout:[UICollectionViewFlowLayout new]]; self.clickView.delegate = self; self.clickView.dataSource = self; [self.view addSubview:self.clickView]; } // existing UICollectionViewController logic @end 

Esto le permite realizar la llamada a playInputClick desde una UIView lugar de un UIViewController .

Para usar los beneficios de playInputClick en UIViewController :

Vista de accesorio de input ficticia:

 @interface Clicker : UIView <UIInputViewAudioFeedback> @end @implementation Clicker - (BOOL)enableInputClicksWhenVisible { return YES; } @end 

Ver con la vista de accesorios de input:

 @interface ControllerView : UIView @end @implementation ControllerView - (BOOL)canBecomeFirstResponder { return YES; } - (UIView *)inputAccessoryView { return [[Clicker alloc] init]; } @end 

Ver controller con vista personalizada:

 @implementation ViewController - (void)loadView { self.view = [[ControllerView alloc] init]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.view becomeFirstResponder]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.view resignFirstResponder]; } @end 

Cuando el object respondedor se convierte en el primer respondedor y inputView (o inputAccessoryView) no es nil, UIKit anima la vista de input en su lugar debajo de la vista principal (o adjunta la vista de accesorios de input a la parte superior de la vista de input).

No hay consecuencias visuales ya que la altura de la vista de Clicker es cero y conforme al protocolo UIInputViewAudioFeedback habilita la funcionalidad [[UIDevice currentDevice] playInputClick] dentro de ViewController .

Mira aquí las cadenas de respuesta y aquí para get vistas accesorias de input.