iOS开发笔记--keyboard相关


最近一个项目有键盘相关的需求:自定义键盘与系统键盘切换。就将键盘相关的知识点顺了一遍。


一、UITextInputTraits 协议

该协议定义了一些与键盘输入相关的属性。所有支持键盘输入的对象都必须接受这个协议,目的是为了与文本输入管理系统正确地交互。

UITextField 和 UITextView ,UISearchBar都支持该协议。


@protocol UITextInputTraits <NSObject>

@optional

@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; 
//  定义输入文本的自动大写类型 default is UITextAutocapitalizationTypeSentences
@property(nonatomic) UITextAutocorrectionType autocorrectionType;        
 // 定义输入文本的自动更正类型 default is UITextAutocorrectionTypeDefault
@property(nonatomic) UITextSpellCheckingType spellCheckingType NS_AVAILABLE_IOS(5_0); 
// 定义输入文本的拼写检查类型 default is UITextSpellCheckingTypeDefault;
@property(nonatomic) UIKeyboardType keyboardType;                         
// 定义键盘类型 default is UIKeyboardTypeDefault
@property(nonatomic) UIKeyboardAppearance keyboardAppearance;             
// 定义键盘外貌类型 default is UIKeyboardAppearanceDefault
@property(nonatomic) UIReturnKeyType returnKeyType;                       

// 定义键盘returnKey的类型 default is UIReturnKeyDefault (See note under UIReturnKeyType enum)
@property(nonatomic) BOOL enablesReturnKeyAutomatically;                  
// default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents)
@property(nonatomic,getter=isSecureTextEntry) BOOL secureTextEntry;      
 // 输入文本是否加密 default is NO

@end 


typedef NS_ENUM(NSInteger, UIKeyboardType) {
    UIKeyboardTypeDefault,                // Default type for the current input method.
    UIKeyboardTypeASCIICapable,          
 // 字母键盘 Displays a keyboard which can enter ASCII characters, non-ASCII keyboards remain active
    UIKeyboardTypeNumbersAndPunctuation,  // Numbers and assorted punctuation.
    UIKeyboardTypeURL,                    // A type optimized for URL entry (shows . / .com prominently).
    UIKeyboardTypeNumberPad,              // A number pad (0-9). Suitable for PIN entry.
    UIKeyboardTypePhonePad,               // A phone pad (1-9, *, 0, #, with letters under the numbers).
    UIKeyboardTypeNamePhonePad,           // A type optimized for entering a person's name or phone number.
    UIKeyboardTypeEmailAddress,           // A type optimized for multiple email address entry (shows space @ . prominently).
#if __IPHONE_4_1 <= __IPHONE_OS_VERSION_MAX_ALLOWED
    UIKeyboardTypeDecimalPad,             // A number pad with a decimal point.
#endif
#if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
    UIKeyboardTypeTwitter,                // A type optimized for twitter text entry (easy access to @ #)
#endif

    UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable, // Deprecated

};

这个属性决定了在输入文本中,是否支持拼写检查。


二、定制键盘


@interface UIResponder (UIResponderInputViewAdditions)

// Called and presented when object becomes first responder.  Goes up the responder chain.
@property (readonly, retain) UIView *inputView NS_AVAILABLE_IOS(3_2);                       
//键盘视图,定制的键盘视图要赋值给该属性
@property (readonly, retain) UIView *inputAccessoryView NS_AVAILABLE_IOS(3_2);   
//键盘辅助视图,即位于键盘视图上面一些额外的辅助性视图,可在上添加辅助功能键

// If called while object is first responder, reloads inputView and inputAccessoryView.  Otherwise ignored.
- (void)reloadInputViews NS_AVAILABLE_IOS(3_2);

@end

UITextField 和 UITextView 都提供了以上方法。




如上图所示,绿色视图为 inputAccessoryView。下面的是定制的键盘视图

示例代码如下

 -  (void)viewDidLoad
{ 
        [super viewDidLoad];

        self.numberTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 120, 280, 80)];
	self.numberTextField.backgroundColor = [UIColor darkGrayColor];
	self.numberTextField.delegate = self;
	self.numberTextField.keyboardType = UIKeyboardTypeNamePhonePad;

        self.numberTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
	self.numberTextField.autocorrectionType = UITextAutocorrectionTypeNo;
	self.numberTextField.spellCheckingType = UITextSpellCheckingTypeNo;
	self.numberTextField.returnKeyType = UIReturnKeySearch;

        _inputView = [[AZStockKeyboardView alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, 216)];
	_inputView.delegate = self;
	self.numberTextField.inputView = _inputView;
	UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
	accessoryView.backgroundColor = [UIColor greenColor];
	self.numberTextField.inputAccessoryView = accessoryView;
	[self.view addSubview:self.numberTextField];
}


切换系统键盘

- (void)customedKeyboardDidChange
{
	self.numberTextField.inputView = nil;
	[self.numberTextField reloadInputViews];
}

系统键盘切换定制键盘

- (void)systemKeyboardDidChange
{
	self.numberTextField.inputView = _inputView;
	[self.numberTextField reloadInputViews];
}

给定制的键盘添加系统键盘按键声音

1.定制键盘视图要继承UIView,接受 UIInputViewAudioFeedback 协议,并实现协议方法

@interface AZStockKeyboardView : UIView<UIInputViewAudioFeedback>
{

}

#pragma mark UIInputViewAudioFeedback protocol methods

- (BOOL)enableInputClicksWhenVisible
{
	return YES;
}


2.在定制的键盘的按键响应的方法中,调用 [[UIDevice currentDevice] playInputClick]

- (void)numberButtonClicked:(id)sender
{
	[[UIDevice currentDevice] playInputClick];
}


三、改造系统键盘

由于需要定制键盘和系统键盘互相切换,就需要将系统键盘的切换键盘的按键响应我们自己的切换键盘方法。

Apple官方并没有提供这种方法,目前可行的做法是将该按键用我们自己的创建的按键将其覆盖。

UITextEffectsWindow       //键盘所在window

UIPeripheralHostView      //键盘视图所在的父视图  定制的键盘视图,辅助视图都放在这个视图上面

UIKeyboardAutomatic      //键盘视图

UIKeyboardImpl               //自己按英文的意思理解的,键盘的实现视图

UIKeyboardLayoutStar     //自己按英文的意思理解的,键盘的布局视图

UIKBKeyplaneView          //

UIKBKeyView                   //根据description判断,是键盘的功能性按键的视图(除字母,数字之外,类似删除键,空格键等)

以上视图都有层级关系,从上到下,上面的视图是下面视图的父视图

完成覆盖按键的任务,需要获取 UIKeyboardAutomatic 视图,然后把定制的切换按键添加到该视图上



获取系统键盘视图

- (UIView *)getSystemKeyboardView
{
	UIView *returnView = nil;
	
	UIWindow *keyboardWindow = nil;
	for (UIWindow *window in [[UIApplication sharedApplication] windows])
	{
		if (![NSStringFromClass([window class]) isEqualToString:NSStringFromClass([UIWindow class])])
		{
			keyboardWindow = window;
			break;
		}
	}
	if (keyboardWindow == nil)
		return nil;

	for (UIView *firstView in [keyboardWindow subviews])
	{
		if ([[firstView description] hasPrefix:@"<UIPeripheralHostView"])
		{
			for (UIView *secondView in [firstView subviews])
			{
				if ([[secondView description] hasPrefix:@"<UIKeyboardAutomatic"])
				{
					returnView = secondView;
				}
			}
		}
	}
	
	return returnView;
}

监听键盘事件

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];


向键盘视图上覆盖按键

- (void)keyboardDidShow:(id)notification
{
	_keyboardDefaultView = [self getSystemKeyboardView];
	if (_keyboardDefaultView)
	{
		_switchNumButton = [UIButton buttonWithType:UIButtonTypeCustom];
		[_switchNumButton setTitle:@"123" forState:UIControlStateNormal];
		[_switchNumButton setBackgroundImage:[UIImage imageNamed:@"num.png"] forState:UIControlStateNormal];
		_switchNumButton.frame = CGRectMake(1, 173, 78, 42);
		[_switchNumButton addTarget:self action:@selector(changeCutomeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
		[_keyboardDefaultView addSubview:_switchNumButton];
	}
}


效果如下:





注意:由于所有系统键盘都是所有程序共享的,所以在当前界面消失前,或者其他类型的输入视图调用键盘前,要将我们自己定制的按键移除。

否则,从其他应用调用该类型键盘,都可以看到我们定制的按键。

同时也应该在调用键盘前,即键盘弹出时,在用我们定制的按键覆盖之前加限定条件


- (void)keyboardDidShow:(id)notification
{
	_keyboardDefaultView = [self getSystemKeyboardView];
	if (_keyboardDefaultView && [_numberTextField isFirstResponder])
	{
		_switchNumButton = [UIButton buttonWithType:UIButtonTypeCustom];
		[_switchNumButton setTitle:@"123" forState:UIControlStateNormal];
		[_switchNumButton setBackgroundImage:[UIImage imageNamed:@"num.png"] forState:UIControlStateNormal];
		_switchNumButton.frame = CGRectMake(1, 173, 78, 42);
		[_switchNumButton addTarget:self action:@selector(changeCutomeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
		[_keyboardDefaultView addSubview:_switchNumButton];
	}
	else
	{
		if (_switchNumButton) {
			[_switchNumButton removeFromSuperview];
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值