Question

I have some trouble with my custom keyboard and playing the "click" sound. I'm using the following classes and defintions.

KeyboardShotInputView.h

#import <UIKit/UIKit.h>

//------------------------------------------------------------------------------
// Protocol defintion
//------------------------------------------------------------------------------

@protocol KeyboardShotInputDelegate

- (void)shotButtonDidTouchDown:(NSString*)value;
- (void)deleteButtonDidTouchDown;

@end

//------------------------------------------------------------------------------
// Interface defintition
//------------------------------------------------------------------------------

@interface KeyboardShotInputView : UIView <UIInputViewAudioFeedback>

@property (nonatomic, strong) id <KeyboardShotInputDelegate> delegate;
@property (strong, nonatomic) IBOutlet UIView *keyboard;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *shotButtonCollection;
@property (weak, nonatomic) IBOutlet UIButton *deleteButton;

- (UIView *) getKeyboardView;
- (IBAction)shotButtonPressed:(id)sender;
- (IBAction)deleteButtonPressed:(id)sender;
@end

KeyboardShotInputView.m

#import "KeyboardShotInputView.h"

@implementation KeyboardShotInputView

@synthesize keyboard;
@synthesize shotButtonCollection;
@synthesize deleteButton;

//------------------------------------------------------------------------------

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) {
        [self loadInputView];
    }        
    return self;
}

//------------------------------------------------------------------------------

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];

    if (self) {
        [self loadInputView];
    }
    return self;
}

//------------------------------------------------------------------------------

- (void)loadInputView
{
    // load nib file
    UINib *inputViewNib = [UINib nibWithNibName:@"KeyboardShotInput" bundle:nil];
    [inputViewNib instantiateWithOwner:self options:nil];

    // layout shot input buttons
    for (UIButton *btn in shotButtonCollection) {
        //[btn.layer setBorderWidth:1.0];
        [btn.layer setCornerRadius:5.0];
        [btn.layer setShadowColor:[UIColor blackColor].CGColor];
        [btn.layer setShadowOpacity:0.9];
        [btn.layer setShadowRadius:1.0];
        [btn.layer setShadowOffset:CGSizeMake(0.0, 1.0)];
    }

    // layout delete button
    [self.deleteButton.layer setBorderWidth:1.0];
    [self.deleteButton.layer setCornerRadius:5.0];
    [self.deleteButton.layer setCornerRadius:5.0];
    [self.deleteButton.layer setShadowColor:[UIColor blackColor].CGColor];
    [self.deleteButton.layer setShadowOpacity:0.9];
    [self.deleteButton.layer setShadowRadius:1.0];
    [self.deleteButton.layer setShadowOffset:CGSizeMake(0.0, 1.0)];
}

//------------------------------------------------------------------------------

/**
 * Enable input clicks.
 */
- (BOOL) enableInputClicksWhenVisible
{
    NSLog(@"enableInputClicksWhenVisible: YES");
    return YES;
}

//------------------------------------------------------------------------------

/**
 * Return Keyboard object.
 *
 * @return UIView of the keyboard.
 */
- (UIView *) getKeyboardView;
{
    return self.keyboard;
}

//------------------------------------------------------------------------------

/**
 * Any of the shot button is pressed.
 *
 * @param sender Shot button object.
 */
- (IBAction)shotButtonPressed:(id)sender
{
    if (!self.delegate) return;

    // play click
    NSLog(@"shotButtonPressed: playInputClick");
    [[UIDevice currentDevice] playInputClick];

    [self.delegate shotButtonDidTouchDown:[(UIButton *)sender currentTitle]];
}

//------------------------------------------------------------------------------

/**
 * The delete button is pressed.
 *
 * @param sender DEL button object.
 */
- (IBAction)deleteButtonPressed:(id)sender
{
    if (!self.delegate) return;

    // play click
    NSLog(@"deleteButtonPressed: playInputClick");
    [[UIDevice currentDevice] playInputClick];
    [self.delegate deleteButtonDidTouchDown];
}

@end

EditShootingResultTableViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    // connect keyboard toolbar
    self.keyboardToolbar = [[KeyboardToolbar alloc] init];
    self.keyboardToolbar.delegate = self;

    // connect shot input keyboard    
    self.keyboardShotInputView = [[KeyboardShotInputView alloc] init];
    self.keyboardShotInputView.delegate = self;

    for (UITextField* tf in self.tfShotCollection) {
        tf.inputView = [self.keyboardShotInputView getKeyboardView];
    }

    //...
}

//------------------------------------------------------------------------------
// @name KeyboardShotInputDelegates

/**
 * Receive a message every time the user touches any shot input button.
 */
- (void)shotButtonDidTouchDown:(NSString *)value
{
   // handle keyboard event here...
}

//------------------------------------------------------------------------------

/**
 * Receive a message every time the user touches the shot delete button.
 */
- (void)deleteButtonDidTouchDown
{
     // handle keyboard event here...
}

Everything is working fine. Even the call of the keyboard delegates. I get all NSLog outputs excepting the NSLog from the method enableInputClicksWhenVisible. Does anyone know what going wrong? I couldn't find any solution since a couple of days. :-(

Regards

Was it helpful?

Solution

Try this :

AudioServicesPlaySystemSound(0x450);

OTHER TIPS

It seems like there is a bug in Apple's implementation; there appears to be some hidden rules about whether or not the UIView subclass can be recognized as implementing the UIInputViewAudioFeedback protocol.

However, this blog post has a working sample that you can try:

http://gregheo.com/blog/ios-custom-keyboard/

In my own attempt at this, I had defined a subview in a xib with the custom keypad controls. It did not work. However, in the sample code referenced in the blog post, he is defining the keypad controls in the root view of the xib - and for some reason this works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top