linux九宫格输入法,解决U3D 4.6 IOS 九宫格输入法不能正常输入中文问题

应该是从U3D4.6后,U3D 在IOS 上九宫格输入法就出问题了。只要打开了hideinput 属性,九宫格输入法就死活不能输入中文,问了很多朋友都没有办法。。那只能自己动手解决了。。

经过多次测试,得到的结论是只有IOS上会出这个bug,那么我就锁定了,keyboard.mm这个文件.开始动手修改。。。

鉴于U3D提供的输入框略丑还太大,还出现了done和cancel按钮(感觉没有必要),于是都动手去掉了。。几番测试下来,得到的结论是,IOS不能输入中文的原因是textfield在输入中文的时候出现了问题。。好尴尬~~既然如此我就用textview替代掉了textfield。。下面是最终修改后的代码。。

#include "Keyboard.h"

#include "DisplayManager.h"

#include "UnityForwardDecls.h"

#include

// Respect values passed from prefix header or CFlags

#ifndef FILTER_EMOJIS_IOS_KEYBOARD

// Set this flag to 0 in order to allow emoji symbols to be entered in the iOS keyboard.

#define FILTER_EMOJIS_IOS_KEYBOARD 1

#endif

static KeyboardDelegate*_keyboard = nil;

static bool_shouldHideInput = false;

static bool_shouldHideInputChanged = false;

static const unsigned kToolBarHeight = 64;

@implementation KeyboardDelegate

{

// UI handling

// in case of single line we use UITextField inside UIToolbar

// in case of multi-line input we use UITextView with UIToolbar as accessory view

// toolbar buttons are kept around to prevent releasing them

// tvOS does not support multiline input thus only UITextField option is implemented

#if UNITY_IOS

UITextView*textView;

UIToolbar*viewToolbar;

NSArray*viewToolbarItems;

#endif

UITextField*textField;

// keep toolbar items for both single- and multi- line edit in NSArray to make sure they are kept around

#if UNITY_IOS

UIToolbar*fieldToolbar;

NSArray*fieldToolbarItems;

#endif

// inputView is view used for actual input (it will be responder): UITextField [single-line] or UITextView [multi-line]

// editView is the "root" view for keyboard: UIToolbar [single-line] or UITextView [multi-line]

UIView*inputView;

UIView*editView;

CGRect_area;

NSString*initialText;

UIKeyboardTypekeyboardType;

BOOL_multiline;

BOOL_inputHidden;

BOOL_active;

BOOL_done;

BOOL_canceled;

BOOL_rotating;

}

@synthesize area;

@synthesize active= _active;

@synthesize done= _done;

@synthesize canceled= _canceled;

@synthesize text;

// While emoji symbols are still shown in the iOS keyboard, they are all filtered by the

// shouldChangeCharactersInRange method below.

#if FILTER_EMOJIS_IOS_KEYBOARD

bool stringContainsEmoji(NSString *string)

{

__block BOOL returnValue = NO;

[string enumerateSubstringsInRange:NSMakeRange(0, [string length])

options:NSStringEnumerationByComposedCharacterSequences

usingBlock: ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop)

{

const unichar hs = [substring characterAtIndex:0];

// Surrogate pair

if(hs >= 0xD800 && hs <= 0xDBFF)

{

if(substring.length > 1)

{

// Compute the code point in the U+10000 - U+10FFFF plane.

const unichar ls = [substring characterAtIndex:1];

const int uc = ((hs - 0xD800) * 0x400) + (ls - 0xDC00) + 0x10000;

// The ranges for the various emoji tables are as follows.

// Musical -> [U+1D000, U+1D24F]

// Miscellaneous Symbols and Pictographs -> [U+1F300, U+1F5FF]

// Emoticons -> [U+1F600, U+1F64F]

// Transport and Map Symbols -> [U+1F680, U+1F6FF]

// Supplemental Symbols and Pictographs -> [U+1F900, U+1F9FF]

if(uc >= 0x1D000 && uc <= 0x1F9FF)

{

returnValue = YES;

}

}

}

else if(substring.length > 1)

{

const unichar ls = [substring characterAtIndex:1];

if(ls == 0x20E3)

{

// Filter all the emojis for numbers.

returnValue = YES;

}

else if(hs >= 0x270A && hs <= 0x270D)

{

// Filter all the various hand symbols (e.g., victory sign, writing hand, etc).

returnValue = YES;

}

}

else

{

// Non surrogate pair.

if(hs >= 0x2100 && hs <= 0x27FF)

{

// Filter the following emoji ranges.

// Letterlike Symbols -> [U+2100, U+214F]

// Number Forms -> [U+2150, U+218F]

// Arrows -> [U+2190, U+21FF]

// Dingbats -> [U+2700, U+27BF]

// Supplemental Arrows-A -> [U+27F0–U+27FF]

returnValue = YES;

}

else if(hs >= 0x2900 && hs <= 0x297F)

{

// Filter Supplemental Arrows-B -> [U+2900, U+297F]

returnValue = YES;

}

else if(hs >= 0x2B05 && hs <= 0x2BFF)

{

// Filter Miscellaneous Symbols and Arrows -> [U+2B00, U+2BFF]

returnValue = YES;

}

}

}];

return returnValue;

}

// See the documentation for this method in http://apple.co/1OMnz8D.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

// Process the input string using the 'stringContainsEmoji' function and return NO or YES

// depending on whether it needs to be added to the UITexField or skipped altogether, respectively.

// We need to do this because Unity's UI doesn't provide proper Unicode support yet.

return !stringContainsEmoji(string);

}

#endif // FILTER_EMOJIS_IOS_KEYBOARD

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{

if ([text isEqualToString:@"\n"]){

//判断输入的字是否是回车,即按下return

//在这里做你响应return键的代码

[self hide];

return NO; //这里返回NO,就代表return键值失效,即页面上按下return,不会出现换行,如果为yes,则输入页面会换行

}

return YES;

}

- (BOOL)textViewShouldReturn:(UITextView*)textFieldObj

{

[self hide];

return YES;

}

- (BOOL)textFieldShouldReturn:(UITextField*)textFieldObj

{

[self hide];

return YES;

}

- (void)textInputDone:(id)sender

{

[self hide];

}

- (void)textInputCancel:(id)sender

{

_canceled = true;

[self hide];

}

- (BOOL)textViewShouldBeginEditing:(UITextView*)view

{

#if !UNITY_TVOS

view.inputAccessoryView = viewToolbar;

#endif

return YES;

}

#if UNITY_IOS

- (void)keyboardDidShow:(NSNotification*)notification;

{

if (notification.userInfo == nil || inputView == nil)

return;

CGRect srcRect= [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

CGRect rect= [UnityGetGLView() convertRect:srcRect fromView:nil];

[self positionInput:rect x:rect.origin.x y:rect.origin.y];

_active = YES;

}

- (void)keyboardWillHide:(NSNotification*)notification;

{

[self systemHideKeyboard];

}

- (void)keyboardDidChangeFrame:(NSNotification*)notification;

{

_active = true;

CGRect srcRect= [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

CGRect rect= [UnityGetGLView() convertRect:srcRect fromView: nil];

if(rect.origin.y >= [UnityGetGLView() bounds].size.height)

[self systemHideKeyboard];

else

[self positionInput:rect x:rect.origin.x y:rect.origin.y];

}

#endif

+ (void)Initialize

{

NSAssert(_keyboard == nil, @"[KeyboardDelegate Initialize] called after creating keyboard");

if(!_keyboard)

_keyboard = [[KeyboardDelegate alloc] init];

}

+ (KeyboardDelegate*)Instance

{

if(!_keyboard)

_keyboard = [[KeyboardDelegate alloc] init];

return _keyboard;

}

#if UNITY_IOS

struct CreateToolbarResult

{

UIToolbar*toolbar;

NSArray*items;

};

- (CreateToolbarResult)createToolbarWithView:(UIView*)view

{

UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0,160,320, kToolBarHeight)];

UnitySetViewTouchProcessing(toolbar, touchesIgnored);

toolbar.hidden = NO;

UIBarButtonItem* inputItem= view ? [[UIBarButtonItem alloc] initWithCustomView:view] : nil;

UIBarButtonItem* doneItem= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(textInputDone:)];

UIBarButtonItem* cancelItem= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(textInputCancel:)];

NSArray* items = view ? @[inputItem, doneItem, cancelItem] : @[doneItem, cancelItem];

toolbar.items = items;

inputItem = nil;

doneItem = nil;

cancelItem = nil;

CreateToolbarResult ret = {toolbar, items};

return ret;

}

#endif

- (id)init

{

NSAssert(_keyboard == nil, @"You can have only one instance of KeyboardDelegate");

self = [super init];

if(self)

{

#if UNITY_IOS

textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 480, 480, 30)];

textView.delegate = self;

textView.font = [UIFont systemFontOfSize:18.0];

textView.hidden = YES;

textView.returnKeyType = UIReturnKeyDone;

#endif

textField = [[UITextField alloc] initWithFrame:CGRectMake(0,0,120,30)];

textField.delegate = self;

textField.borderStyle = UITextBorderStyleRoundedRect;

textField.font = [UIFont systemFontOfSize:20.0];

textField.clearButtonMode = UITextFieldViewModeWhileEditing;

#define CREATE_TOOLBAR(t, i, v)\

do {\

CreateToolbarResult res = [self createToolbarWithView:v];\

t = res.toolbar;\

i = res.items;\

} while(0)

#if UNITY_IOS

//CREATE_TOOLBAR(viewToolbar, viewToolbarItems, nil);

CREATE_TOOLBAR(fieldToolbar, fieldToolbarItems, textField);

#endif

#undef CREATE_TOOLBAR

#if UNITY_IOS

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

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];

#endif

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textInputDone:) name:UITextFieldTextDidEndEditingNotification object:nil];

}

return self;

}

- (void) setTextInputTraits: (id) traits

withParam: (KeyboardShowParam) param

withCap: (UITextAutocapitalizationType) capitalization

{

traits.keyboardType= param.keyboardType;

traits.autocorrectionType = param.autocorrectionType;

traits.secureTextEntry = param.secure;

traits.keyboardAppearance = param.appearance;

traits.autocapitalizationType = capitalization;

}

- (void)setKeyboardParams:(KeyboardShowParam)param

{

if(_active)

[self hide];

initialText = param.text ? [[NSString alloc] initWithUTF8String: param.text] : @"";

UITextAutocapitalizationType capitalization = UITextAutocapitalizationTypeSentences;

if(param.keyboardType == UIKeyboardTypeURL || param.keyboardType == UIKeyboardTypeEmailAddress)

capitalization = UITextAutocapitalizationTypeNone;

#if UNITY_IOS

//_multiline = param.multiline;

_multiline = true;

if (_multiline)

{

textView.text = initialText;

[self setTextInputTraits:textView withParam:param withCap:capitalization];

}

else

{

textField.text = initialText;

[self setTextInputTraits:textField withParam:param withCap:capitalization];

textField.placeholder = [NSString stringWithUTF8String:param.placeholder];

}

inputView = _multiline ? textView : textField;

editView = _multiline ? textView : fieldToolbar;

#else // UNITY_TVOS

textField.text = initialText;

[self setTextInputTraits:textField withParam:param withCap:capitalization];

textField.placeholder = [NSString stringWithUTF8String:param.placeholder];

inputView = textField;

editView = textField;

#endif

[self shouldHideInput:_shouldHideInput];

_done= NO;

_canceled= NO;

_active= YES;

}

// we need to show/hide keyboard to react to orientation too, so extract we extract UI fiddling

- (void)showUI

{

// if we unhide everything now the input will be shown smaller then needed quickly (and resized later)

// so unhide only when keyboard is actually shown (we will update it when reacting to ios notifications)

editView.hidden = YES;

[UnityGetGLView() addSubview:editView];

[inputView becomeFirstResponder];

}

- (void)hideUI

{

[inputView resignFirstResponder];

[editView removeFromSuperview];

editView.hidden = YES;

}

- (void)systemHideKeyboard

{

_active = editView.isFirstResponder;

editView.hidden = YES;

_area = CGRectMake(0,0,0,0);

}

- (void)show

{

[self showUI];

}

- (void)hide

{

[self hideUI];

_done = YES;

}

- (void)updateInputHidden

{

if(_shouldHideInputChanged)

{

[self shouldHideInput:_shouldHideInput];

_shouldHideInputChanged = false;

}

textField.returnKeyType = _inputHidden ? UIReturnKeyDone : UIReturnKeyDefault;

editView.hidden= _inputHidden ? YES : NO;

inputView.hidden= _inputHidden ? YES : NO;

}

#if UNITY_IOS

- (void)positionInput:(CGRect)kbRect x:(float)x y:(float)y

{

if(_multiline)

{

// use smaller area for iphones and bigger one for ipads

//int height = UnityDeviceDPI() > 300 ? 75 : 100;

//editView.frame= CGRectMake(0, y - kToolBarHeight, kbRect.size.width, height);

int height = UnityDeviceDPI() > 300 ? 38 : 100;

editView.frame= CGRectMake(0, y - height, kbRect.size.width, height);

}

else

{

CGRect statusFrame= [UIApplication sharedApplication].statusBarFrame;

unsigned statusHeight= statusFrame.size.height;

editView.frame= CGRectMake(0, y - kToolBarHeight - statusHeight, kbRect.size.width, kToolBarHeight);

inputView.frame= CGRectMake(inputView.frame.origin.x,

inputView.frame.origin.y,

kbRect.size.width - 3*18 - 2*50,

inputView.frame.size.height);

}

_area = CGRectMake(x, y, kbRect.size.width, kbRect.size.height);

[self updateInputHidden];

}

#endif

- (CGRect)queryArea

{

return editView.hidden ? _area : CGRectUnion(_area, editView.frame);

}

+ (void)StartReorientation

{

if(_keyboard && _keyboard.active)

{

[CATransaction begin];

[_keyboard hideUI];

[CATransaction commit];

// not pretty but seems like easiest way to keep "we are rotating" status

_keyboard->_rotating = YES;

}

}

+ (void)FinishReorientation

{

if(_keyboard && _keyboard->_rotating)

{

[CATransaction begin];

[_keyboard showUI];

[CATransaction commit];

_keyboard->_rotating = NO;

}

}

- (NSString*)getText

{

if (_canceled)

return initialText;

else

{

#if UNITY_TVOS

return [textField text];

#else

return _multiline ? [textView text] : [textField text];

#endif

}

}

- (void) setTextWorkaround:(id)textInput text:(NSString*)newText

{

UITextPosition* begin = [textInput beginningOfDocument];

UITextPosition* end = [textInput endOfDocument];

UITextRange* allText = [textInput textRangeFromPosition:begin toPosition:end];

[textInput setSelectedTextRange:allText];

[textInput insertText:newText];

}

- (void)setText:(NSString*)newText

{

#if UNITY_IOS

// We can't use setText on iOS7 because it does not update the undo stack.

// We still prefer setText on other iOSes, because an undo operation results

// in a smaller selection shown on the UI

if(_ios70orNewer && !_ios80orNewer)

[self setTextWorkaround: (_multiline ? textView : textField) text:newText];

if(_multiline)

textView.text = newText;

else

textField.text = newText;

#else

textField.text = newText;

#endif

}

- (void)shouldHideInput:(BOOL)hide

{

if(hide)

{

switch(keyboardType)

{

case UIKeyboardTypeDefault: hide = YES;break;

case UIKeyboardTypeASCIICapable: hide = YES;break;

case UIKeyboardTypeNumbersAndPunctuation: hide = YES;break;

case UIKeyboardTypeURL: hide = YES;break;

case UIKeyboardTypeNumberPad: hide = NO;break;

case UIKeyboardTypePhonePad: hide = NO;break;

case UIKeyboardTypeNamePhonePad: hide = NO;break;

case UIKeyboardTypeEmailAddress: hide = YES;break;

default: hide = NO;break;

}

}

_inputHidden = hide;

}

@end

//==============================================================================

//

// Unity Interface:

extern "C" void UnityKeyboard_Create(unsigned keyboardType, int autocorrection, int multiline, int secure, int alert, const char* text, const char* placeholder)

{

#if UNITY_TVOS

// Not supported. The API for showing keyboard for editing multi-line text

// is not available on tvOS

multiline = false;

#endif

static const UIKeyboardType keyboardTypes[] =

{

UIKeyboardTypeDefault,

UIKeyboardTypeASCIICapable,

UIKeyboardTypeNumbersAndPunctuation,

UIKeyboardTypeURL,

UIKeyboardTypeNumberPad,

UIKeyboardTypePhonePad,

UIKeyboardTypeNamePhonePad,

UIKeyboardTypeEmailAddress,

};

static const UITextAutocorrectionType autocorrectionTypes[] =

{

UITextAutocorrectionTypeNo,

UITextAutocorrectionTypeDefault,

};

static const UIKeyboardAppearance keyboardAppearances[] =

{

UIKeyboardAppearanceDefault,

UIKeyboardAppearanceAlert,

};

KeyboardShowParam param =

{

text, placeholder,

keyboardTypes[keyboardType],

autocorrectionTypes[autocorrection],

keyboardAppearances[alert],

(BOOL)multiline, (BOOL)secure

};

[[KeyboardDelegate Instance] setKeyboardParams:param];

}

extern "C" void UnityKeyboard_Show()

{

// do not send hide if didnt create keyboard

// TODO: probably assert?

if(!_keyboard)

return;

[[KeyboardDelegate Instance] show];

}

extern "C" void UnityKeyboard_Hide()

{

// do not send hide if didnt create keyboard

// TODO: probably assert?

if(!_keyboard)

return;

[[KeyboardDelegate Instance] hide];

}

extern "C" void UnityKeyboard_SetText(const char* text)

{

[KeyboardDelegate Instance].text = [NSString stringWithUTF8String: text];

}

extern "C" NSString* UnityKeyboard_GetText()

{

return [KeyboardDelegate Instance].text;

}

extern "C" int UnityKeyboard_IsActive()

{

return (_keyboard && _keyboard.active) ? 1 : 0;

}

extern "C" int UnityKeyboard_IsDone()

{

return (_keyboard && _keyboard.done) ? 1 : 0;

}

extern "C" int UnityKeyboard_WasCanceled()

{

return (_keyboard && _keyboard.canceled) ? 1 : 0;

}

extern "C" void UnityKeyboard_SetInputHidden(int hidden)

{

_shouldHideInput= hidden;

_shouldHideInputChanged= true;

// update hidden status only if keyboard is on screen to avoid showing input view out of nowhere

if(_keyboard && _keyboard.active)

[_keyboard updateInputHidden];

}

extern "C" int UnityKeyboard_IsInputHidden()

{

return _shouldHideInput ? 1 : 0;

}

extern "C" void UnityKeyboard_GetRect(float* x, float* y, float* w, float* h)

{

CGRect area = _keyboard ? _keyboard.area : CGRectMake(0,0,0,0);

// convert to unity coord system

floatmultX= (float)GetMainDisplaySurface()->targetW / UnityGetGLView().bounds.size.width;

floatmultY= (float)GetMainDisplaySurface()->targetH / UnityGetGLView().bounds.size.height;

*x = 0;

*y = area.origin.y * multY;

*w = area.size.width * multX;

*h = area.size.height * multY;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值