在集合视图控制器中播放键盘单击声音

时间:2016-08-29 01:29:34

标签: ios objective-c uicollectionview

我创建了一个UICollectionViewController的子类,用作inputAccessoryViewController中的自定义UITextViewhttps://developer.apple.com/reference/uikit/uiresponder/1621124-inputaccessoryviewcontroller

当您使用playInputClick点击集合视图中的单元格时,我想播放键盘单击声音。 https://developer.apple.com/reference/uikit/uidevice/1620050-playinputclick

我无法弄清楚如何在集合视图中使用它。它使用inputAccessoryView的{​​{1}}属性来处理这样的简单视图,但是我不确定在集合视图控制器层次结构中使用哪个子类视图来获取键盘单击声音。

UITextView

我也知道您可以使用@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 redColor]; [[UITextView appearance] setInputAccessoryView:_inputAccessoryView]; // ... } @end 播放键盘咔嗒声但如果他们禁用了键盘咔嗒声,则这不符合用户的设置。

3 个答案:

答案 0 :(得分:2)

playInputClick中使用UIViewController的好处:

虚拟输入附件视图:

@interface Clicker : UIView <UIInputViewAudioFeedback>

@end

@implementation Clicker

- (BOOL)enableInputClicksWhenVisible
{
    return YES;
}

@end

使用输入附件视图查看:

@interface ControllerView : UIView

@end

@implementation ControllerView

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (UIView *)inputAccessoryView
{
    return [[Clicker alloc] init];
}

@end

使用自定义视图查看控制器:

@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
  

当响应者对象成为第一个响应者和inputView时   (或inputAccessoryView)不是nil,UIKit将输入视图设置为动画   放置在父视图下方(或将输入附件视图附加到   输入视图的顶部。)

由于Clicker视图的高度为零,并且符合UIInputViewAudioFeedback协议,[[UIDevice currentDevice] playInputClick]内的ViewController功能启用,因此没有视觉效果。

查看响应者链here和输入附件视图here

答案 1 :(得分:1)

不要使用UICollectionViewController,而是将KeyboardClickView定义为UICollectionView的子类,并将其放在UIViewController上。

@interface KeyboardClickView : UICollectionView <UIInputViewAudioFeedback>

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout {
    self = [super initWithFrame:frame collectionViewLayout:layout];

    // existing implementation

新的视图控制器看起来像这样:

@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

这样,您就可以从playInputClick而不是UIView拨打UIViewController

答案 2 :(得分:0)

这是bteapot答案的有效的 Swift 4.2 (iOS 11和12)版本。

private class ClickerDummyView: UIView, UIInputViewAudioFeedback {
    var enableInputClicksWhenVisible: Bool { return true }
}

private class ClickerControllerView: UIView {
    override var canBecomeFirstResponder: Bool {
        return true
    }

    override var inputAccessoryView: UIView? {
        return ClickerDummyView()
    }
}


class ClickingViewController: UIViewController {

    override func loadView() {
        self.view = ClickerControllerView()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        view.becomeFirstResponder()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        view.resignFirstResponder()
    }
}

现在需要时,可以从UIDevice.current.playInputClick()类中调用ClickingViewController,并且会触发键盘点击声(相对于系统设置)。