好了,终于成功了@Jack Hua的解决方案对我不起作用,因为我无法将文本字段设置为
FirstResponder
因为有很多
UIMaskedTextField
在scrollview上,屏蔽文本字段不是scrollview的第一个子视图,但它确实给了我一些想法!我开始怀疑,在设置text属性时,textfield的初始化不知怎么搞砸了光标的位置,我相信这就是正在发生的事情,只是无法证明这一点,因为视图的初始化是在幕后发生的。但我怀疑通过
EditMask
属性使初始化更快发生,并使设置光标位置成为可能。这也从一开始就设置了掩码,消除了用户对字段格式的任何疑问。以下是我的“最终”代码:
class UIMaskedTextField : UITextField
{
private string editmask = "";
public String EditMask
{
get => editmask;
set
{
if ((value != ""))
{
editmask = value;
this.Text = editmask.Replace("#", "_"); ;
}
}
}
public UIMaskedTextField()
{
this.Delegate = new PhoneMaskTextViewDelegate(this);
}
}
class PhoneMaskTextViewDelegate : UITextFieldDelegate
{
private UIMaskedTextField MyParent;
int index = 0;
public PhoneMaskTextViewDelegate(UIMaskedTextField parent)
{
MyParent = parent;
}
public override void DidChangeSelection(UITextField textField)
{
int y = textField.Text.IndexOf("_");
if (y > -1)
{
var newPosition = textField.GetPosition(textField.BeginningOfDocument, y);
textField.SelectedTextRange = textField.GetTextRange(newPosition, newPosition);
}
}
public override bool ShouldChangeCharacters(UITextField textField, NSRange range, string replacementString)
{
const string maskCharacters = "()-/ ";
string newText = "";
int val;
if (replacementString != "")
{
int fieldlength = 10;
string text = textField.Text;
if (text == "")
{
newText = MyParent.EditMask.Replace("#", "_");
}
else
{
newText = text;
}
string totalChar = newText.Replace(" ", "");
totalChar = totalChar.Replace("(", "");
totalChar = totalChar.Replace(")", "");
totalChar = totalChar.Replace("-", "");
totalChar = totalChar.Replace("_", "");
if (Utils.IsNumeric(replacementString))
{
if ((totalChar + replacementString).Length <= fieldlength)
{
if (replacementString != "")
{
index = newText.IndexOf("_");
if (index > -1)
{
StringBuilder sb = new StringBuilder(newText);
char character = char.Parse(replacementString);
sb[index] = character;
newText = sb.ToString();
textField.Text = newText;
NSRange therange = new NSRange(index, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Location + 1);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
newText = "";
}
}
}
} else
{
UITextRange position = textField.SelectedTextRange;
string x = position.ToString();
int positionofcursor = Convert.ToInt32(x.Substring(x.IndexOf("(") + 1, x.IndexOf(",") - x.IndexOf("(") - 1));
string characterInPosition = "";
do {
positionofcursor -= 1;
if (positionofcursor > -1)
{
characterInPosition = textField.Text.Substring(positionofcursor, 1);
int j = maskCharacters.IndexOf(characterInPosition);
}else
{
break;
}
} while (maskCharacters.IndexOf(characterInPosition) > -1);
if (positionofcursor > -1)
{
StringBuilder sb = new StringBuilder(textField.Text);
sb[positionofcursor] = char.Parse("_");
textField.Text = sb.ToString();
NSRange therange = new NSRange(positionofcursor, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Location);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
}
return Int32.TryParse(newText, out val);
}
}