自定义标签渲染器在 Xamarin iOS 的滚动列表视图中显示错误的文本样式

Posted

技术标签:

【中文标题】自定义标签渲染器在 Xamarin iOS 的滚动列表视图中显示错误的文本样式【英文标题】:custom LabelRenderer shows wrong text style inside list view on scroll on Xamarin iOS 【发布时间】:2022-01-13 05:35:13 【问题描述】:

我正在开发一个应用程序,该应用程序需要一个列表视图,该列表视图在用户删除时具有带有 NSUnderlineStyle 的文本标签。 根据要求,用户在详细屏幕中有删除/恢复选项。删除确认后,文本标签应为该特定单元格的下划线样式。

我在 Xamarin ios 中为 NSUnderlineStyle 使用 LabelRenderer。

但当前 ListView 显示带有下划线样式的文本标签,用户在列表视图滚动时不会删除该标签。下划线样式在列表视图滚动时从一个单元格标签交换到另一个。

下面是我的示例代码。

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)

    base.OnElementPropertyChanged(sender, e);

    if (this.Control == null)
    
        return;
    

    if (this.Element is ExtendedLabel extended)
    
        var strikethroughStyle = extended.IsStrikeThrough ? NSUnderlineStyle.Single : NSUnderlineStyle.None;
        this.Control.AttributedText = new NSMutableAttributedString(
            extended.Text ?? string.Empty,
            this.Control.Font,
            strikethroughStyle: strikethroughStyle);
    

【问题讨论】:

基本症状是“下划线样式在滚动时从一个单元格交换到另一个单元格”。要对此进行调试,请编辑问题以显示整个自定义渲染器 .cs - 您需要在其他地方进行一些更改。此外,显示包含这些条目的列表视图或集合视图的 xaml。 【参考方案1】:

这是 TableView Cell Resue 的常见问题,tableView 将重用单元格用于可见(内部屏幕截图)的单元格,因此它会显示以前的样式。

为了解决这个问题,我们可以在每次单元格显示时强制设置样式。

ListView 创建自定义渲染器,并在WillDisplay 方法中执行此操作,在此之前我们需要覆盖TableView's Delegate

[assembly: ExportRenderer(typeof(ListView), typeof(MyRenderer))]
namespace FormsApp.iOS


    public class MyDelegate : UITableViewDelegate
    
        List<Model> data;
        public MyDelegate(List<Model> _data)
        
            data = _data;
        

        public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
        
            var views = cell.ContentView.Subviews;

            foreach (var view in views)
            
                if(view is LabelRenderer renderer)
                
                    UILabel label = renderer.Control;
                    var strikethroughStyle = data[indexPath.Row].YourProperty?NSUnderlineStyle.Single : NSUnderlineStyle.None;
                    label.AttributedText = new NSMutableAttributedString(
                        label.Text ?? string.Empty,
                        label.Font,
                        strikethroughStyle: strikethroughStyle);
                
            
        
    

    public class MyRenderer : ListViewRenderer
    
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        
            base.OnElementChanged(e);

            if (e.OldElement != null)
            
                // Unsubscribe
            

            if (e.NewElement != null)
            
                IEnumerable<Model> data = (IEnumerable<Model>)Element.ItemsSource;
                Control.Delegate = new MyDelegate(data.ToList());
            
        
       

【讨论】:

以上是关于自定义标签渲染器在 Xamarin iOS 的滚动列表视图中显示错误的文本样式的主要内容,如果未能解决你的问题,请参考以下文章

在 Xamarin Forms 自定义标签渲染器中,增加边界的大小

Xamarin.iOS 自定义渲染器调用 SetNativeControl 的性能很慢

创建自定义导航栏渲染器以在 xamarin 表单 IOS 项目中添加自定义后退按钮图标

Xamarin ios 自定义 WkWebViewRenderer 滚动事件

MvvmCross 与 Xamarin.Forms 和自定义 iOS 渲染器 - 防止导航滑动 iOS - MasterDetail

Xamarin iOS Autolayout:自动调整各种设备的宽度和垂直滚动,同时保持水平滚动禁用演示链接