ios - 我有两个高度不同的单元格。当我删除第一个时,第二个获得第一个的高度

标签 ios xamarin xamarin.ios mvvmcross

一些上下文

在此屏幕中,您可以添加和删除人员。并非所有字段都是必需的,因此单元格高度是动态的。

问题

如果我先添加一个完成所有字段的人,然后添加未完成所有字段的第二个人,然后删除第一个人,则第二个人排在第一位,但布局与第一人称相同

重要

在我删除第一个人后,如果我向上滚动直到剩余的单元格离开屏幕,它就会自行修复

代码

这是表格源

namespace xXxx.xXxx.iOS
{
    public class SiniestroParticipantesSource : MvxTableViewSource
    {
        private readonly SiniestroParticipantesViewModel viewModel;

        public SiniestroParticipantesSource(UITableView tableView, SiniestroParticipantesViewModel viewModel)
            : base(tableView)
        {
            this.UseAnimations = true;
            this.AddAnimation = UITableViewRowAnimation.Top;
            this.RemoveAnimation = UITableViewRowAnimation.Middle;
            this.viewModel = viewModel;

            tableView.RegisterNibForCellReuse(UINib.FromName(PersonaDenunciaCellView.Key, NSBundle.MainBundle), PersonaDenunciaCellView.Key);
        }

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
            tableView.DeselectRow(indexPath, true);
            var itemPersona = this.viewModel.Personas[indexPath.Section];
            this.viewModel.AgregarCommand.Execute(itemPersona);
        }

        protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
        {
            var cell = (PersonaDenunciaCellView)tableView.DequeueReusableCell(PersonaDenunciaCellView.Key, indexPath);
            return cell;
        }

        public override nint RowsInSection(UITableView tableview, nint section)
        {
            return 1;
        }

        public override nint NumberOfSections(UITableView tableView)
        {
            return this.viewModel.Personas.Count;
        }

        protected override object GetItemAt(NSIndexPath indexPath)
        {
            return this.viewModel.Personas[indexPath.Section];
        }
    }
}

这是单元格 View

namespace xXxx.xXxx.iOS
{
    public partial class PersonaDenunciaCellView : MvxTableViewCell
    {
        public static readonly NSString Key = new NSString("PersonaDenunciaCellView");
        public static readonly UINib Nib;

        static PersonaDenunciaCellView()
        {
            Nib = UINib.FromName("PersonaDenunciaCellView", NSBundle.MainBundle);
        }

        protected PersonaDenunciaCellView(IntPtr handle) : base(handle)
        {

            this.DelayBind(() =>
            {
                var set = this.CreateBindingSet<PersonaDenunciaCellView, PersonaDenunciaItemViewModel>();

                set.Bind(btnRemove).To(vm => vm.RemoveCommand);

                set.Bind(lblNombre).To(vm => vm.Persona.Persona.Nombre);

                set.Bind(lblTipoDoc).To(vm => vm.Persona.Persona.TipoDoc.Descripcion);
                set.Bind(tipoDocVisibilityConst).For("Priority").To(vm => vm.Persona.Persona.Nrodoc).WithConversion("iOSVisibility", true);

                set.Bind(lblNrodoc).To(vm => vm.Persona.Persona.Nrodoc);
                set.Bind(nroDocVisibilityConst).For("Priority").To(vm => vm.Persona.Persona.Nrodoc).WithConversion("iOSVisibility", true);

                set.Bind(lblMailContacto).To(vm => vm.Persona.MailContacto);
                set.Bind(mailContactoVisibilityConst).For("Priority").To(vm => vm.Persona.MailContacto).WithConversion("iOSVisibility", true);

                set.Bind(lblTelContacto).To(vm => vm.Persona.TelContacto);
                set.Bind(telContactoVisibilityConst).For("Priority").To(vm => vm.Persona.TelContacto).WithConversion("iOSVisibility", true);

                set.Bind(lblLesionado).To(vm => vm.Persona.Lesionado).WithConversion("Lesionado");

                set.Bind(vehiculoVisibilityConst).For("Priority").To(vm => vm.Persona.Patente).WithConversion("iOSVisibility", true);
                set.Bind(viewVehiculo).For("Visibility").To(vm => vm.Persona.Patente).WithConversion("Visibility");
                set.Bind(lblPatente).To(vm => vm.Persona.Patente);
                set.Bind(lblCiaSeguroDesc).To(vm => vm.Persona.CiaSeguroDesc);

                set.Apply();
            });
        }
    }
}

单元格 View 模型

namespace xXxx.xXxx.Core.ViewModels.Items
{

    public class PersonaDenunciaItemViewModel:MvxViewModel
    {
        private readonly IMvxMessenger messenger;
        private readonly IUserInteraction userInteraction;

        public string Index { get; set; }

        public PersonaDenunciaItemViewModel (SiniestroCarga.PersonaDenuncia persona, IMvxMessenger messenger, IUserInteraction userInteraction, string index)
        {
            this.messenger = messenger;
            this.userInteraction = userInteraction;
            this.Persona = persona;
            this.Index = index;
        }

        private SiniestroCarga.PersonaDenuncia persona;
        public SiniestroCarga.PersonaDenuncia Persona
        {
            get
            {
                return this.persona;
            }
            set
            {
                this.persona = value;
                this.RaisePropertyChanged(() => this.Persona);
            }
        }

        private ICommand removeCommand;
        public ICommand RemoveCommand
        {
            get
            {
                return this.removeCommand = this.removeCommand ?? new MvxCommand(this.RemovePersona);
            }
        }

        private void RemovePersona()
        {
            this.userInteraction.Confirm("Are you sure?", () =>
            {
                this.messenger.Publish(new RemovePersonaDenunciaMessage(this, this.Persona, this.Index));
            }, null, "OK", "Cancel");
        }
    }

}

最后一个 messenger.Publish 在另一个 ViewModel 上订阅了这个

OnRemovePersonaDenuncia = message =>
                {
                    var listPersonas = new ObservableCollection<PersonaDenunciaItemViewModel>(this.Personas);
                    listPersonas.Remove(this.Personas.First(p => p.Index == message.Index));
                    this.Personas = listPersonas;
                }

更新

将 RemoveCommand 的实现更改为此

this.Personas.Remove(this.Personas.First(p => p.Index == message.Index));

使得当我按下删除按钮时,模拟器关闭而没有任何错误。 Xamarin Studio 上的应用程序跟踪显示了这一点

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/UITableView.m:1700

最佳答案

当内容高度为动态时,iOS 无法正确计算单元格的高度。这很烦人,但您可以覆盖 SiniestroParticipantesSource 中的 GetHeightForRowEstimatedHeight 以根据数据计算每个单元格的确切高度:

public override nfloat EstimatedHeight(UITableView tableView, NSIndexPath indexPath) => 
    GetHeightForRow(tableView, indexPath);

public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
    var data = (PersonaDenunciaItemViewModel)ItemsSource.ElementAt(indexPath.Row);
    var cell = (PersonaDenunciaCellView)tableView.DequeueReusableCell(PersonaDenunciaCellView.Key, indexPath);

    // TODO set the cell data manually (ignoring bindings)
    // i.e: **cell.lblNombre = data.Persona.Persona.Nombre**; // and every other field required

    cell.SetNeedsLayout();
    cell.LayoutIfNeeded();

    var size = cell.ContentView.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize);
    return NMath.Ceiling(size.Height) + 1;
}

这是一个 example使用完全相同的代码。

关于ios - 我有两个高度不同的单元格。当我删除第一个时,第二个获得第一个的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39355751/

相关文章:

ios - 使用 AFNetworking 3.0 上传图片

ios - 生成 iOS 证书时遇到问题

ios - 如何使用自动布局选择哪个标签更宽?

android - 在焦点监听器中更改复合可绘制对象时,EditText 会无限触发焦点更改事件

ios - 如何修复 xamarin iOS 链接器以防止删除代码以防止应用程序崩溃?

iphone-sdk-3.0 - Monotouch 设置状态栏隐藏 - API 更改安全

objective-c - 协作 Objective C 和 monotuch

ios - Plot_Gallery_iOS 中的实时绘图不会更新 iPad 中的绘图范围

ios - xamarin代码的OCR阅读器?我也可以使用网络 API 请提出任何建议?

android - 在 Xamarin 中处理 Intent