首页 > 解决方案 > Xamarin.Forms iOS CursorPosition 没有被兑现

问题描述

在我的 Xamarin.Forms 应用程序中,我有一个设置光标位置的行为(该行为充当我们输入字段的掩码)。

CursorPosition 是通过调用来设置的:targetEntry.CursorPosition = newCursorPosition。这在 Android 上运行得很好,但在 iOS 上,光标总是移到文本的末尾,它是 iOS 版本特定的错误,还是只是全面?

有关该行为的所有其他内容(确保正确屏蔽文本,正确删除作为用户输入数据的指南的下划线字符)按其应有的方式工作。如果需要,我可以发布更多代码

编辑:newCursorPosition 是一个静态 int 变量

编辑 2:包括我的代码

公共类 DurationViewMaskBehavior : 行为 { 公共静态 DurationViewMaskBehavior 实例 = 新 DurationViewMaskBehavior(); 私有静态 int cursorPosition = 0;

    protected override void OnAttachedTo(BorderlessEntry entry) {
        entry.TextChanged += OnInput;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(BorderlessEntry entry) {
        entry.TextChanged -= OnInput;
        base.OnDetachingFrom(entry);
    }

    /// <summary>
    /// This method exists to ensure that if the user tried to shape the field to be something it shouldn't
    /// that it will return the mask to the correct format; this is to ensure that we only have valid data and also that 
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    private bool PatternMatchCheck(string text) {

        var regex = @"^(([0-9]\d{1}|__|[0-9]_|[0-9]|[0-9]*__|[0-9]\d{1}_| *) Min, ([0-9]\d{1}|__|[0-9]_|[0-9]|[0-9]__|[0-9]\d{1}_|) Sec|((Min, Sec)|[0-9]+ Min, Sec|Min, [0-9]+ Sec))$";

        var match = Regex.Match(text, regex, RegexOptions.IgnoreCase);

        return match.Success;
    }

    private void OnInput(object sender, TextChangedEventArgs args) {

        //Only fire this behavior when the user actually inputs some type of value
        if(!string.IsNullOrWhiteSpace(args.NewTextValue)) {

            var text = args.NewTextValue;

            //How this works so far:
            //At first you get the input, so text.length == 1 is fine. Then
            //it updates itself, so really for every input this event fires twice. 
            //After that we will have to look at the actual text itself so we can use 
            //the index instead

            var targetObject = ((BorderlessEntry)sender);

            if(!PatternMatchCheck(args.NewTextValue) && args.OldTextValue.Length > 2) {
                targetObject.Text = args.OldTextValue;
                return;
            }

            if (text.Length == 1) {
                targetObject.Text = $"{text}_ Min, __ Sec";
                cursorPosition = 1;
            } 

            if(text.Contains("_")) {
                if (text.Length > 1 && (text[2] != '_' || text[1] != '_')) {
                    if (text[2] == '_' && text[0] != '_') {
                        targetObject.Text = $"{text.Substring(0, 2)} Min, __ Sec";
                        cursorPosition = 8;
                    }
                }

                if (text.Length > 1 && text[8] != '_' && text[9] == '_' && text[8] != ' ') {
                    targetObject.Text = $"{text.Substring(0, 2)} Min, {text[8]}_ Sec";
                    cursorPosition = 9;
                }

                if (text.Length > 1 && text[8] != '_' && text[9] != '_') {
                    targetObject.Text = $"{text.Substring(0, 2)} Min, {text.Substring(8, 2)} Sec";
                    cursorPosition = text.Length-1;
                }
            }


            targetObject.CursorPosition = cursorPosition;
        }
    }
}

标签: c#xamarin.forms

解决方案


弄清楚为什么,看起来 iOS 需要我绑定另一个 .TextChanged 事件来处理光标的设置。它很奇怪而且很落后,但它确实有效。

private void SetCursor(object sender, TextChangedEventArgs args) {
            ((BorderlessEntry)sender).CursorPosition = cursorPosition;
        }

if(isRegistered) {
                    targetObject.TextChanged -= SetCursor;
                    isRegistered = false;
                }
                else {
                    targetObject.TextChanged += SetCursor;
                    isRegistered = true;
                }

推荐阅读