c# iOS 无法将光标定位在 UITextField 中的位置 1
c# iOS Can NOT position cursor in UITextField in position 1
无论我做什么,我都无法将光标设置到此字符串中的位置 1 (___) ___-____
位置 1 是紧跟在开头 (
之后的位置。我在委托的 EditingStarted
方法中执行此操作,作为指南,我遵循代码 。目前我的代码是:
public override void EditingStarted(UITextField textField)
{
if (MyParent.EditMask != "")
{
textField.Text = MyParent.EditMask.Replace("#", "_");
// Set cursor position
NSRange therange = new NSRange(index, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Length - 1);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
}
光标总是在关闭 )
后立即出现,我没有做任何改变。我不知道为什么。我试过获取第一个下划线的位置:
int position = textField.Text.IndexOf("_");
NSRange therange = new NSRange(position, 0);
但同样,这会导致光标紧跟在结束 )
之后。有人看出我做错了什么吗?
**** 更新 ****
为了让人们理解上下文,上面的代码是我创建的名为 UIMaskedTextField
的 class 的一部分,用于处理用户界面中的所有 mask/text 输入格式。 class 是:
class UIMaskedTextField : UITextField
{
public string EditMask { get; set; }
public UIMaskedTextField()
{
this.Delegate = new MaskTextViewDelegate(this);
}
}
class MaskTextViewDelegate : UITextFieldDelegate
{
private UIMaskedTextField MyParent;
int index = 0;
public MaskTextViewDelegate(UIMaskedTextField parent)
{
MyParent = parent;
}
public override void EditingStarted(UITextField textField)
{
if (MyParent.EditMask != "")
{
textField.Text = MyParent.EditMask.Replace("#", "_");
// Set cursor position
int position = textField.Text.IndexOf("_");
NSRange therange = new NSRange(position, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Location);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
}
public override bool ShouldChangeCharacters(UITextField textField, NSRange range, string replacementString)
{
int fieldlength = 10; // MyParent.EditMask.Length;
string text = textField.Text;
int NeedASpace = MyParent.EditMask.IndexOf(" ");
string newText = "";
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("_", "");
int val;
if ((totalChar + replacementString).Length <= fieldlength) {
if (replacementString != "")
{
index = newText.IndexOf("_");
StringBuilder sb = new StringBuilder(newText);
char character = char.Parse(replacementString);
sb[index] = character;
newText = sb.ToString();
textField.Text = newText;
// Set cursor to next position, this works flawlessly
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
{ // Still working the backspace key, so not done here yet.
if (text.Length > 1)
{
newText = text.Substring(0, text.Length - 1);
}
else
{
newText = "";
}
}
}
return Int32.TryParse(newText, out val);
}
}
要将光标定位在 UITextField 中的位置 1:
public partial class ViewController : UIViewController
{
public ViewController (IntPtr handle) : base (handle)
{
}
UITextField textfield1 { get; set; }
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
var frame = new CGRect(10, 10, 300, 40);
textfield1 = new UITextField(frame);
textfield1.Text = "(___) ___-____";
textfield1.Delegate = new myDelegate();
View.Add(textfield1);
textfield1.BecomeFirstResponder();
}
}
public class myDelegate : UITextFieldDelegate {
public override void EditingStarted(UITextField textField)
{
var arbitraryValue = 1;
var newPosition = textField.GetPosition(textField.BeginningOfDocument, arbitraryValue);
textField.SelectedTextRange = textField.GetTextRange(newPosition, newPosition);
}
}
更新:
public override void DidChangeSelection(UITextField textField)
{
var arbitraryValue = 1;
var newPosition = textField.GetPosition(textField.BeginningOfDocument, arbitraryValue);
textField.SelectedTextRange = textField.GetTextRange(newPosition, newPosition);
}
好的,终于可以使用了。 @Jack Hua 的解决方案对我不起作用,因为我无法将文本字段设置为 FirstResponder
,因为滚动视图上有许多 UIMaskedTextField
,屏蔽的文本字段不是第一个 sub-views 在滚动视图上,但它确实给了我一些想法!我开始怀疑在设置文本 属性 时文本字段的初始化以某种方式搞砸了光标位置,我相信这就是正在发生的事情,只是无法证明它因为视图的初始化是发生在幕后。但是我怀疑通过 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)
{
// place the cursor in the first fill podition
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; // MyParent.EditMask.Length;
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;
// Set cursor to next position
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
{ // Backspace/Delete pressed
UITextRange position = textField.SelectedTextRange;
string x = position.ToString();
int positionofcursor = Convert.ToInt32(x.Substring(x.IndexOf("(") + 1, x.IndexOf(",") - x.IndexOf("(") - 1));
string characterInPosition = "";
// make sure we're not deleting a mask character
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);
}
}
无论我做什么,我都无法将光标设置到此字符串中的位置 1 (___) ___-____
位置 1 是紧跟在开头 (
之后的位置。我在委托的 EditingStarted
方法中执行此操作,作为指南,我遵循代码
public override void EditingStarted(UITextField textField)
{
if (MyParent.EditMask != "")
{
textField.Text = MyParent.EditMask.Replace("#", "_");
// Set cursor position
NSRange therange = new NSRange(index, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Length - 1);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
}
光标总是在关闭 )
后立即出现,我没有做任何改变。我不知道为什么。我试过获取第一个下划线的位置:
int position = textField.Text.IndexOf("_");
NSRange therange = new NSRange(position, 0);
但同样,这会导致光标紧跟在结束 )
之后。有人看出我做错了什么吗?
**** 更新 ****
为了让人们理解上下文,上面的代码是我创建的名为 UIMaskedTextField
的 class 的一部分,用于处理用户界面中的所有 mask/text 输入格式。 class 是:
class UIMaskedTextField : UITextField
{
public string EditMask { get; set; }
public UIMaskedTextField()
{
this.Delegate = new MaskTextViewDelegate(this);
}
}
class MaskTextViewDelegate : UITextFieldDelegate
{
private UIMaskedTextField MyParent;
int index = 0;
public MaskTextViewDelegate(UIMaskedTextField parent)
{
MyParent = parent;
}
public override void EditingStarted(UITextField textField)
{
if (MyParent.EditMask != "")
{
textField.Text = MyParent.EditMask.Replace("#", "_");
// Set cursor position
int position = textField.Text.IndexOf("_");
NSRange therange = new NSRange(position, 0);
UITextPosition start = textField.GetPosition(textField.BeginningOfDocument, therange.Location);
UITextPosition end = textField.GetPosition(start, therange.Length);
textField.SelectedTextRange = textField.GetTextRange(start, end);
}
}
public override bool ShouldChangeCharacters(UITextField textField, NSRange range, string replacementString)
{
int fieldlength = 10; // MyParent.EditMask.Length;
string text = textField.Text;
int NeedASpace = MyParent.EditMask.IndexOf(" ");
string newText = "";
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("_", "");
int val;
if ((totalChar + replacementString).Length <= fieldlength) {
if (replacementString != "")
{
index = newText.IndexOf("_");
StringBuilder sb = new StringBuilder(newText);
char character = char.Parse(replacementString);
sb[index] = character;
newText = sb.ToString();
textField.Text = newText;
// Set cursor to next position, this works flawlessly
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
{ // Still working the backspace key, so not done here yet.
if (text.Length > 1)
{
newText = text.Substring(0, text.Length - 1);
}
else
{
newText = "";
}
}
}
return Int32.TryParse(newText, out val);
}
}
要将光标定位在 UITextField 中的位置 1:
public partial class ViewController : UIViewController
{
public ViewController (IntPtr handle) : base (handle)
{
}
UITextField textfield1 { get; set; }
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
var frame = new CGRect(10, 10, 300, 40);
textfield1 = new UITextField(frame);
textfield1.Text = "(___) ___-____";
textfield1.Delegate = new myDelegate();
View.Add(textfield1);
textfield1.BecomeFirstResponder();
}
}
public class myDelegate : UITextFieldDelegate {
public override void EditingStarted(UITextField textField)
{
var arbitraryValue = 1;
var newPosition = textField.GetPosition(textField.BeginningOfDocument, arbitraryValue);
textField.SelectedTextRange = textField.GetTextRange(newPosition, newPosition);
}
}
更新:
public override void DidChangeSelection(UITextField textField)
{
var arbitraryValue = 1;
var newPosition = textField.GetPosition(textField.BeginningOfDocument, arbitraryValue);
textField.SelectedTextRange = textField.GetTextRange(newPosition, newPosition);
}
好的,终于可以使用了。 @Jack Hua 的解决方案对我不起作用,因为我无法将文本字段设置为 FirstResponder
,因为滚动视图上有许多 UIMaskedTextField
,屏蔽的文本字段不是第一个 sub-views 在滚动视图上,但它确实给了我一些想法!我开始怀疑在设置文本 属性 时文本字段的初始化以某种方式搞砸了光标位置,我相信这就是正在发生的事情,只是无法证明它因为视图的初始化是发生在幕后。但是我怀疑通过 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)
{
// place the cursor in the first fill podition
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; // MyParent.EditMask.Length;
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;
// Set cursor to next position
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
{ // Backspace/Delete pressed
UITextRange position = textField.SelectedTextRange;
string x = position.ToString();
int positionofcursor = Convert.ToInt32(x.Substring(x.IndexOf("(") + 1, x.IndexOf(",") - x.IndexOf("(") - 1));
string characterInPosition = "";
// make sure we're not deleting a mask character
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);
}
}