Forum Xamarin.iOS
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Two cells with different heights. If I remove the 1st one, the 2nd one gets the height of the first

Some context

In this screen you can add and remove people. Not all fields are required, so the cell height is dynamic.

The problem

If I add first a person with all the fields completed, then a second person with not all fields completed, and then I remove the first person, the second person takes the first place but with the layout of the first person

IMPORTANT

After I remove the first person, if I scroll up until the remaining cell is off screen, then it fixes itself

Graphic example

I add the first person (full size image)

First person

I add the second person (full size image)

Second person

Then delete the first one (full size image)

Delete the first person

Code

This is the table source

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];
        }
    }
}

This is the cell 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();
            });
        }
    }
}

Cell ViewModel

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");
        }
    }

}

And that last messenger.Publish is subscribed to this on another ViewModel

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

Updates

Changing the implementation of RemoveCommand to this

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

Makes that, when I press the remove button, the simulator closes without any error. The application trace on Xamarin Studio shows this

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

Sign In or Register to comment.