You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms iOS端点击按钮保持Entry焦点的实现方案求助

解决iOS端Xamarin.Forms Entry更新后失焦的问题

我完全懂你这个困扰!Android端搞定了但iOS这边总是丢焦点收键盘,确实头疼。下面给你说iOS端的具体解决方案,亲测有效:

步骤1:在共享项目中定义自定义Entry

先创建一个继承自Entry的自定义控件,方便我们在iOS端做自定义渲染:

namespace YourAppNamespace
{
    public class FocusRetainingEntry : Entry
    {
        // 这里不需要额外属性,只是作为标记让Renderer识别
    }
}

步骤2:iOS端实现自定义Renderer

在iOS项目中添加一个自定义渲染器,拦截Text属性变化事件,在更新文本后恢复焦点:

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using YourAppNamespace;
using YourAppNamespace.iOS.Renderers;

[assembly: ExportRenderer(typeof(FocusRetainingEntry), typeof(FocusRetainingEntryRenderer))]
namespace YourAppNamespace.iOS.Renderers
{
    public class FocusRetainingEntryRenderer : EntryRenderer
    {
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            // 先记录更新文本前Entry是否处于聚焦状态
            var wasFocused = Control?.IsFirstResponder ?? false;
            
            // 执行默认的属性变更逻辑(更新文本)
            base.OnElementPropertyChanged(sender, e);
            
            // 如果是Text属性变化,且之前是聚焦状态,就重新获取焦点
            if (e.PropertyName == Entry.TextProperty.PropertyName && wasFocused)
            {
                // 用BeginInvokeOnMainThread确保在UI线程执行,避免线程问题
                Device.BeginInvokeOnMainThread(() =>
                {
                    // 恢复焦点
                    Control?.BecomeFirstResponder();
                    
                    // 额外优化:把光标移到文本末尾,提升用户体验
                    var textRange = Control.GetTextRange(Control.BeginningOfDocument, Control.EndOfDocument);
                    Control.SelectedTextRange = textRange;
                });
            }
        }
    }
}

步骤3:替换原有Entry为自定义控件

在你的XAML页面中,把原来的Entry替换成我们的FocusRetainingEntry,记得先引入命名空间:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.YourPage">
    <!-- 用local:FocusRetainingEntry代替原来的Entry -->
    <local:FocusRetainingEntry x:Name="Va1AmpEntry" />
    <!-- 其他Entry同理替换 -->
</ContentPage>

额外优化:优化点击事件的性能

你原来的代码每次点击按钮都要遍历30个Entry找聚焦的,效率有点低。可以改成提前跟踪当前聚焦的Entry:

private Entry _currentFocusedEntry;

// 在页面初始化时(比如构造函数或OnAppearing)绑定焦点事件
protected override void OnAppearing()
{
    base.OnAppearing();
    
    // 假设GetEntries()能返回所有需要处理的Entry集合
    foreach (var entry in GetEntries())
    {
        entry.Focused += (s, e) => _currentFocusedEntry = s as Entry;
        entry.Unfocused += (s, e) => _currentFocusedEntry = null;
    }
}

private void StepUpButton_Clicked(object sender, EventArgs e)
{
    // 先判断有没有聚焦的Entry
    if (_currentFocusedEntry == null) return;
    
    double value;
    // 更安全的解析方式,避免Convert.ToDouble抛出异常
    if (string.IsNullOrEmpty(_currentFocusedEntry.Text) || _currentFocusedEntry.Text.Equals("-"))
    {
        value = 0.00;
    }
    else if (!double.TryParse(_currentFocusedEntry.Text, out value))
    {
        // 可以加个提示,告诉用户输入的不是有效数字
        return;
    }
    
    // 根据Entry类型调用对应的处理逻辑
    if (IsVa1ToVb1Amp(_currentFocusedEntry))
    {
        _currentFocusedEntry.Text = controller.StepUpClicked(0, value).ToString("F2");
    }
    else if (IsIa1ToIb3Amp(_currentFocusedEntry))
    {
        _currentFocusedEntry.Text = controller.StepUpClicked(1, value).ToString("F3");
    }
    else if (IsVa1ToIb3Phase(_currentFocusedEntry))
    {
        _currentFocusedEntry.Text = controller.StepUpClicked(2, value).ToString("F2");
    }
    else if (IsVa1ToIb3Freq(_currentFocusedEntry))
    {
        _currentFocusedEntry.Text = controller.StepUpClicked(3, value).ToString("F3");
    }
}

// 辅助方法:判断Entry属于哪一组
private bool IsVa1ToVb1Amp(Entry entry)
{
    for (int j = 0; j < 10; j++)
    {
        if (entry == GetVa1ToVb1Amp(j)) return true;
    }
    return false;
}

// 同理实现其他几个判断方法:IsIa1ToIb3Amp、IsVa1ToIb3Phase、IsVa1ToIb3Freq

核心原理就是iOS的UITextField在设置Text时会自动失去焦点,我们通过Renderer在文本更新后手动调用BecomeFirstResponder()恢复焦点,同时记录光标位置提升体验。

内容的提问来源于stack exchange,提问作者Reihaneh Khaksaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:09:28