我创建了一个UICollectionViewController的子类,用作inputAccessoryViewController
中的自定义UITextView
。
https://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
播放键盘咔嗒声但如果他们禁用了键盘咔嗒声,则这不符合用户的设置。
答案 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
功能启用,因此没有视觉效果。
答案 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
,并且会触发键盘点击声(相对于系统设置)。