當(dāng)前越來越多的iOS應(yīng)用開始使用html進(jìn)行交互顯示,卻會發(fā)現(xiàn)在UIWebView
彈出的鍵盤比UITextView
的鍵盤多出了左右移動以及完成按鈕高氮,那么如何去掉這些我們并不需要的按鈕呢?蘋果官方并沒有給出方法腾啥,所以我們只能夠自己來解決芋类。
webview_keyboard.png
對于不同的iOS版本霜旧,我們的處理方法也會不同错忱,因?yàn)楣俜經(jīng)]有提供方法,所有的方法都是需要自己去發(fā)現(xiàn)和修改颁糟。這里只寫出iOS7以上版本的方法:
func hideKeyBoard() -> Void {
for window in UIApplication.sharedApplication().windows {
if !window.isMemberOfClass(UIWindow.self) {
let keyboardWindow = window
if #available(iOS 9.0, *) {
self.removeAccessoryBarForiOS9(keyboardWindow as UIView)
} else if #available(iOS 8.0, *) {
self.removeAccessoryBarForiOS8(keyboardWindow as UIView)
} else {
self.removeAccessoryBarForiOS7(keyboardWindow as UIView)
}
}
}
if #available(iOS 9.0, *) {
self.removeAccessoryBarForiOS9(UIApplication.sharedApplication().windows.last! as UIView)
}
}
func removeAccessoryBarForiOS9(keyboardWindow:UIView) -> Void {
for possibleFormView:UIView in keyboardWindow.subviews {
if possibleFormView.isMemberOfClass(NSClassFromString("UIInputSetContainerView")!) {
for subviewOfInputSetContainerView in possibleFormView.subviews {
if subviewOfInputSetContainerView.isMemberOfClass(NSClassFromString("UIInputSetHostView")!) {
for subviewOfInputSetHostView in subviewOfInputSetContainerView.subviews {
// 隱藏工具條NSClassFromString
if subviewOfInputSetHostView.isMemberOfClass(NSClassFromString("UIWebFormAccessory")!) {
subviewOfInputSetHostView.layer.opacity = 0
subviewOfInputSetHostView.frame = CGRectZero
} else if (subviewOfInputSetHostView.isMemberOfClass(NSClassFromString("_UIRemoteKeyboardPlaceholderView")!)) {
subviewOfInputSetHostView.layer.opacity = 0
subviewOfInputSetHostView.frame = CGRectZero
// 這里使用了私有方法獲取對應(yīng)的accessorBar航背,然后進(jìn)行隱藏
var accessory = subviewOfInputSetHostView.performSelector(Selector("placeheldView")).takeRetainedValue()
if accessory.isMemberOfClass(NSClassFromString("UIWebFormAccessory")!) {
let accessory = accessory as! UIView
accessory.layer.opacity = 0
accessory.frame = CGRectZero
}
}
// 鍵盤背景, UIKBInputBackdropView有兩個只隱藏上面的
else if subviewOfInputSetHostView.isMemberOfClass(NSClassFromString("UIKBInputBackdropView")!) && subviewOfInputSetHostView.frame.size.height < 100 {
subviewOfInputSetHostView.layer.opacity = 0
subviewOfInputSetHostView.userInteractionEnabled = false
}
}
}
}
}
}
}
func removeAccessoryBarForiOS8(keyboardWindow:UIView) -> Void {
for possibleFormView:UIView in keyboardWindow.subviews {
if possibleFormView.isMemberOfClass(NSClassFromString("UIInputSetContainerView")!) {
for subviewOfInputSetContainerView in possibleFormView.subviews {
if subviewOfInputSetContainerView.isMemberOfClass(NSClassFromString("UIInputSetHostView")!) {
for subviewOfInputSetHostView in subviewOfInputSetContainerView.subviews {
// 隱藏工具條
if subviewOfInputSetHostView.isMemberOfClass(NSClassFromString("UIWebFormAccessory")!) {
subviewOfInputSetHostView.layer.opacity = 0
subviewOfInputSetHostView.frame = CGRectZero
}
// 鍵盤背景, UIKBInputBackdropView有兩個只隱藏上面的
else if subviewOfInputSetHostView.isMemberOfClass(NSClassFromString("UIKBInputBackdropView")!) && subviewOfInputSetHostView.frame.size.height < 100 {
subviewOfInputSetHostView.layer.opacity = 0
subviewOfInputSetHostView.userInteractionEnabled = false
}
}
}
}
}
}
}
func removeAccessoryBarForiOS7(keyboardWindow:UIView) -> Void {
for possibleFormView:UIView in keyboardWindow.subviews {
if possibleFormView.isMemberOfClass(NSClassFromString("UIPeripheralHostView")!) {
for subviewOfPeripheralHostView in possibleFormView.subviews {
// 隱藏工具條
if subviewOfPeripheralHostView.isMemberOfClass(NSClassFromString("UIWebFormAccessory")!) {
subviewOfPeripheralHostView.layer.opacity = 0
subviewOfPeripheralHostView.frame = CGRectZero
}
// 鍵盤背景, UIKBInputBackdropView有兩個只隱藏上面的
else if subviewOfPeripheralHostView.isMemberOfClass(NSClassFromString("UIKBInputBackdropView")!) && subviewOfPeripheralHostView.frame.size.height < 100 {
subviewOfPeripheralHostView.layer.opacity = 0
subviewOfPeripheralHostView.userInteractionEnabled = false
}
}
}
}
}
實(shí)際中喉悴,隱藏鍵盤accessory
后的樣子如下圖:
webview_keyboard_hideaccessory.png
需要注意的是棱貌,在示例代碼使用設(shè)置layer透明,frame為空來進(jìn)行隱藏箕肃,而不使用removeFromSuperView
婚脱,是因?yàn)槭褂昧?code>removeFromSuperView,在鍵盤重新布局時會導(dǎo)致crash勺像。當(dāng)然如果有朋友解決了crash障贸,使用removeFromSuperView
會更好。
附:
- 上面示例代碼Github地址
- 使用
removeFromSuperView
產(chǎn)生crash的崩潰棧:
2016-07-06 14:10:32.018 WebViewKeyBoard[10846:930540] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7f82a172d880 V:[_UIRemoteKeyboardPlaceholderView:0x7f82a14e7e30]-(0)-[_UIKBCompatInputView:0x7f82a16f9950]>
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2016-07-06 14:10:32.018 WebViewKeyBoard[10846:930540] *** Assertion failure in -[UIInputSetHostView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/NSLayoutConstraint_UIKitAdditions.m:590
2016-07-06 14:10:32.025 WebViewKeyBoard[10846:930540] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up layout with view hierarchy unprepared for constraint.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000105517d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001072bbdeb objc_exception_throw + 48
2 CoreFoundation 0x0000000105517bea +[NSException raise:format:arguments:] + 106
3 Foundation 0x0000000105968d5a -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
4 UIKit 0x0000000106626b99 __120-[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:]_block_invoke_2 + 254
5 UIKit 0x000000010662698b -[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 385
6 UIKit 0x0000000106626e04 -[UIView(UIConstraintBasedLayout) _tryToAddConstraintWithoutUpdatingConstraintsArray:roundingAdjustment:mutuallyExclusiveConstraints:] + 65
7 UIKit 0x0000000106626f7d -[UIView(UIConstraintBasedLayout) _tryToAddConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 288
8 UIKit 0x000000010662719f -[UIView(UIConstraintBasedLayout) _addConstraint:] + 274
9 UIKit 0x0000000106627438 __50-[UIView(UIConstraintBasedLayout) addConstraints:]_block_invoke + 197
10 Foundation 0x00000001058f23d3 -[NSISEngine withBehaviors:performModifications:] + 155
11 UIKit 0x0000000106626577 -[UIView(UIConstraintBasedLayout) _withAutomaticEngineOptimizationDisabled:] + 58
12 UIKit 0x0000000106627348 -[UIView(UIConstraintBasedLayout) addConstraints:] + 379
13 UIKit 0x00000001066b5531 -[UIInputWindowController updateViewConstraints] + 3558
14 UIKit 0x00000001066b1fde -[UIInputSetHostView _didChangeKeyplaneWithContext:] + 224
15 UIKit 0x000000010650f1cc -[_UIKBCompatInputView _didChangeKeyplaneWithContext:] + 87
16 UIKit 0x0000000106004397 -[UIKeyboard _didChangeKeyplaneWithContext:] + 324
17 UIKit 0x0000000105fe7b04 -[UIKeyboardImpl _didChangeKeyplaneWithContext:] + 1100
18 UIKit 0x000000010620d5a3 -[UIKeyboardLayoutStar(UIKeyboardLayoutJapanese50OnFlick) _didChangeKeyplaneWithContext:] + 183
19 UIKit 0x00000001061f121e -[UIKeyboardLayoutStar setKeyplaneName:] + 4512
20 UIKit 0x0000000106209c37 -[UIKeyboardLayoutStar setShift:] + 158
21 UIKit 0x0000000105fec46a -[UIKeyboardImpl notifyShiftState] + 73
22 CoreFoundation 0x000000010543cc37 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
23 CoreFoundation 0x000000010543cba7 __CFRunLoopDoObservers + 391
24 CoreFoundation 0x00000001054326c4 __CFRunLoopRun + 836
25 CoreFoundation 0x00000001054320f8 CFRunLoopRunSpecific + 488
26 GraphicsServices 0x0000000109badad2 GSEventRunModal + 161
27 UIKit 0x0000000105d3ff09 UIApplicationMain + 171
28 WebViewKeyBoard 0x000000010532a242 main + 114
29 libdyld.dylib 0x0000000107d7f92d start + 1
30 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException