CollectionView jumping

zoyusibuzoyusibu Member ✭✭
edited July 7 in Xamarin.Forms

Hi guys and girls!
In my project it contains CollectionView, which contain viewes with switches. After toggled the switch, each waste item increases in size. Everything is good if the waste is at the top, but i have problems with the bottom of the view: the list (collectionview) automatically scrolls up.
What needs to be done so that the list does not scroll?

Code in view of CollectionView. I don't use XAML

>! public class PaymentBillRelationViewCell: StackLayout
    {
        private readonly XLabel DocumentName;
        private readonly XLabel Date;
        private readonly XLabel Sum;
        private readonly XLabel Remainder;
        private readonly NamedSwitch RelationshipSwitch;
        private readonly NamedInputForForm inputSum;
        private readonly Divider middleDivider;
        private readonly Divider bottomDivider;
        private readonly Action<PaymentBillRelationViewData> scrollItemToStart;
        private readonly Action<PaymentBillRelationViewData, bool> changeRelationStatus;
        private readonly Action<PaymentBillRelationViewData, decimal?> changeRelationAmount;
        private readonly Func<PaymentBillRelationViewData, bool> isShowRemainder;
        private readonly Func<PaymentBillRelationViewData, decimal> calculateRelationRemainder;
        private readonly Func<PaymentBillRelationViewData, string> checkRelationForError;
        private readonly Action updateHeader;

        private readonly Grid grid;

        public PaymentBillRelationViewCell(
            Action<PaymentBillRelationViewData> scrollItemToStart,
            Action<PaymentBillRelationViewData, bool> changeRelationStatus,
            Action<PaymentBillRelationViewData, decimal?> changeRelationAmount,
            Func<PaymentBillRelationViewData, bool> isShowRemainder,
            Func<PaymentBillRelationViewData, decimal> calculateRelationRemainder,
            Func<PaymentBillRelationViewData, string> checkRelationForError,
            Action updateHeader,
            bool hasBottomButton = false,
            string textForButton = "",
            Action goToCreateMoney = null)
        {
            this.scrollItemToStart = scrollItemToStart;
            this.changeRelationStatus = changeRelationStatus;
            this.changeRelationAmount = changeRelationAmount;
            this.isShowRemainder = isShowRemainder;
            this.calculateRelationRemainder = calculateRelationRemainder;
            this.checkRelationForError = checkRelationForError;
            this.updateHeader = updateHeader;
            grid = new Grid
                   {
                       ColumnDefinitions = new ColumnDefinitionCollection
                                           {
                                               new ColumnDefinition
                                               {
                                                   Width = GridLength.Auto
                                               },
                                               new ColumnDefinition
                                               {
                                                   Width = GridLength.Auto
                                               },
                                               new ColumnDefinition
                                               {
                                                   Width = GridLength.Star
                                               },
                                               new ColumnDefinition
                                               {
                                                   Width = Sizes.FormItemRightPadding
                                               }
                                           },
                       RowDefinitions = new RowDefinitionCollection
                                        {
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto },
                                            new RowDefinition { Height = GridLength.Auto }
                                        }
                   };

            grid.Children.Add(GetTopBoldDivider().Export(out var boldDividerLayout), 0, 0);
            Grid.SetColumnSpan(boldDividerLayout, 4);
            grid.Children.Add(new XLabel
                              {
                                  FontSize = FontSizes.Standard17,
                                  VerticalOptions = LayoutOptions.CenterAndExpand,
                                  HorizontalOptions = LayoutOptions.Start,
                                  VerticalTextAlignment = TextAlignment.Center,
                                  Margin = new Thickness
                                           {
                                               Left = Sizes.FormItemLeftPadding
                                           }
                              }.Export(out DocumentName), 0, 1);
            Grid.SetColumnSpan(DocumentName, 3);
            grid.Children.Add(new XLabel
                              {
                                  FontSize = FontSizes.Standard17,
                                  VerticalOptions = LayoutOptions.CenterAndExpand,
                                  VerticalTextAlignment = TextAlignment.Center,
                                  Margin = new Thickness
                                           {
                                               Left = Sizes.FormItemLeftPadding
                                           }
                              }.Export(out Date), 0, 2);
            grid.Children.Add(new XLabel
                              {
                                  FontSize = FontSizes.Standard17,
                                  VerticalOptions = LayoutOptions.CenterAndExpand,
                                  VerticalTextAlignment = TextAlignment.Center,
                                  Margin = new Thickness
                                           {
                                               Left = Sizes.FormItemLeftPadding
                                           }
                              }.Export(out Sum), 0, 3);
            Grid.SetColumnSpan(Sum, 3);
            grid.Children.Add(new NamedSwitch("").Export(out RelationshipSwitch), 2, 1);
            grid.Children.Add(new XLabel
                              {
                                  FontSize = FontSizes.DashboardCellText,
                                  VerticalOptions = LayoutOptions.End,
                                  HorizontalOptions = LayoutOptions.StartAndExpand,
                                  VerticalTextAlignment = TextAlignment.Center,
                                  TextColor = Colors.TextDisableColor,
                                  Margin = new Thickness
                                           {
                                               Left = Sizes.FormItemLeftPadding
                                           },
                                  IsVisible = false
                              }.Export(out Remainder), 0, 4);
            Grid.SetRowSpan(RelationshipSwitch, 4);
            Grid.SetColumnSpan(Remainder, 4);
            grid.Children.Add(new Divider().Export(out middleDivider), 0, 5);
            Grid.SetColumnSpan(middleDivider, 4);
            grid.Children.Add(new NamedInputForForm(new NamedInput("Связано, ₽", true, maxLength: 30)
                                                    {
                                                        Keyboard = Keyboard.Numeric,
                                                        Padding = new Thickness { Bottom = 8 },
                                                    }).Export(out inputSum), 0, 6);
            Grid.SetColumnSpan(inputSum, 4);
            grid.Children.Add(new Divider
                              {
                                  VerticalOptions = LayoutOptions.EndAndExpand,
                                  FullWidth = true
                              }.Export(out bottomDivider), 0, 7);
            Grid.SetColumnSpan(bottomDivider, 4);
            RelationshipSwitch.SwitchControl.Toggled += (_, __) => ChangeRelation();
            inputSum.Content.TextChanged += (_, __) => ChangeRelatedSum();
            inputSum.DividerVisible = false;
            grid.BackgroundColor = Color.White;
            Children.Add(grid);
            if (hasBottomButton)
                Children.Add(new PaymentBillRelationFooter(textForButton, goToCreateMoney));
        }

        private LightStackLayout GetTopBoldDivider()
        {
            return new LightStackLayout
                   {
                       Children =
                       {
                           new Divider(Colors.LightGrayDivider)
                           {
                               VerticalOptions = LayoutOptions.End,
                               FullWidth = true,
                               HeightRequest = 16,
                           },
                           new Divider
                           {
                               VerticalOptions = LayoutOptions.End,
                               FullWidth = true
                           }
                       }
                   };
        }

        protected override void OnBindingContextChanged()
        {
            var data = (PaymentBillRelationViewData) BindingContext;
            if (data == null)
                return;

            SetData(data);
            base.OnBindingContextChanged();
        }

        private void SetData(PaymentBillRelationViewData item)
        {
            if (inputSum.IsVisible == RelationshipSwitch.Value)
                return;

            if (isShowRemainder.Invoke(item))
            {
                Remainder.IsVisible = true;
                Remainder.Text =
                    $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
                middleDivider.SetValue(Grid.RowProperty, 5);
                inputSum.SetValue(Grid.RowProperty, 6);
                RelationshipSwitch.SetValue(Grid.RowSpanProperty, 4);
            }
            else
            {
                Remainder.IsVisible = false;
                middleDivider.SetValue(Grid.RowProperty, 6);
                inputSum.SetValue(Grid.RowProperty, 7);
                RelationshipSwitch.SetValue(Grid.RowSpanProperty, 3);
            }

            inputSum.Focused += () => scrollItemToStart.Invoke(item);
            RelationshipSwitch.Value = item.ConnectedSumToCurrentDoc > 0;
            inputSum.IsVisible = RelationshipSwitch.Value;
            middleDivider.IsVisible = RelationshipSwitch.Value;
            if (inputSum.IsVisible)
                inputSum.Text = item.ConnectedSumToCurrentDoc != 0
                                    ? item.ConnectedSumToCurrentDoc.ToString()
                                    : "";

            DocumentName.Text = item.DocumentName;
            Date.Text = item.DateOfDocument;
            Sum.Text = $"{item.AllAmountMoney.FormatMoneyWithCoopeks()} {MoneyHelpers.RubleSumbol}";
        }

        private void ChangeRelatedSum()
        {
            var item = (PaymentBillRelationViewData) BindingContext;
            if (item == null)
                return;
            decimal? inputSum = null;
            try
            {
                if (this.inputSum.Text.Length > 0)
                    inputSum = decimal.Parse(this.inputSum.Text);
            }
            catch (Exception e)
            {
            }

            changeRelationAmount?.Invoke(item, inputSum);
            if (isShowRemainder.Invoke(item))
                Remainder.Text =
                    $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
            var textError = checkRelationForError?.Invoke(item);
            if (textError.Length > 0)
            {
                this.inputSum.Content.Hint = textError;
                this.inputSum.Content.HintColor = Color.Red;
                bottomDivider.BackgroundColor = Color.Red;
            }
            else
            {
                this.inputSum.Content.Hint = "Связано, ₽";
                this.inputSum.Content.HintColor = Colors.TextDisableColor;
                bottomDivider.BackgroundColor = Colors.Divider;
            }

            updateHeader?.Invoke();
        }

        private void ChangeRelation()
        {
            var item = (PaymentBillRelationViewData) BindingContext;
            if (inputSum.IsVisible == RelationshipSwitch.Value)
                return;
            inputSum.IsVisible = RelationshipSwitch.Value;
            middleDivider.IsVisible = RelationshipSwitch.Value;
            changeRelationStatus?.Invoke(item, RelationshipSwitch.Value);
            inputSum.Text = RelationshipSwitch.Value ? item.ConnectedSumToCurrentDoc.ToString() : "";
            if (isShowRemainder.Invoke(item))
                Remainder.Text =
                    $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
            updateHeader?.Invoke();
        }
    }

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    I can't test this custom stacklayout because it is not independent.
    Could you please create a collection sample with this custom cell so that I can run it on my side to see your issues.
    Then we can dig further to see what causes that.

  • zoyusibuzoyusibu Member ✭✭

    @LandLu
    i remove custom views from stacklayout and collectionview all the same jumping.
    I also noticed that this happens only when there is a cell with a different size.

    DataTemplate (crooked but functional):

    public class PaymentBillRelationViewCell: StackLayout
    {
    private readonly Label DocumentName;
    private readonly Label Date;
    private readonly Label Sum;
    private readonly Label Remainder;
    private readonly Switch RelationshipSwitch;
    private readonly Entry inputSum;
    private readonly Divider middleDivider;
    private readonly Divider bottomDivider;
    private readonly bool isShowRemainder;
    private readonly Action makeVisible;
    private readonly Action scrollItemToStart;
    private readonly Action<PaymentBillRelationViewData, bool> changeRelationStatus;
    private readonly Action<PaymentBillRelationViewData, decimal?> changeRelationAmount;
    private readonly Func<PaymentBillRelationViewData, decimal> calculateRelationRemainder;
    private readonly Func<PaymentBillRelationViewData, string> checkRelationForError;
    private readonly Action updateHeader;
    private readonly Grid grid;

     public PaymentBillRelationViewCell(
         Action<PaymentBillRelationViewData> makeVisible,
         Action<PaymentBillRelationViewData> scrollItemToStart,
         Action<PaymentBillRelationViewData, bool> changeRelationStatus,
         Action<PaymentBillRelationViewData, decimal?> changeRelationAmount,
         Func<PaymentBillRelationViewData, decimal> calculateRelationRemainder,
         Func<PaymentBillRelationViewData, string> checkRelationForError,
         Action updateHeader,
         bool isShowRemainder = false,
         bool hasRelation = true,
         bool hasBottomButton = false,
         string textForButton = "",
         Action goToCreateMoney = null)
     {
         this.makeVisible = makeVisible;
         this.scrollItemToStart = scrollItemToStart;
         this.changeRelationStatus = changeRelationStatus;
         this.changeRelationAmount = changeRelationAmount;
         this.isShowRemainder = isShowRemainder;
         this.calculateRelationRemainder = calculateRelationRemainder;
         this.checkRelationForError = checkRelationForError;
         this.updateHeader = updateHeader;
         grid = new Grid
                {
                    ColumnDefinitions = new ColumnDefinitionCollection
                                        {
                                            new ColumnDefinition
                                            {
                                                Width = GridLength.Auto
                                            },
                                            new ColumnDefinition
                                            {
                                                Width = GridLength.Auto
                                            },
                                            new ColumnDefinition
                                            {
                                                Width = GridLength.Star
                                            },
                                            new ColumnDefinition
                                            {
                                                Width = Sizes.FormItemRightPadding
                                            }
                                        },
                    RowDefinitions = new RowDefinitionCollection
                                     {
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto },
                                         new RowDefinition { Height = GridLength.Auto }
                                     }
                };
    
         grid.Children.Add(GetTopBoldDivider().Export(out var boldDividerLayout), 0, 0);
         Grid.SetColumnSpan(boldDividerLayout, 4);
         grid.Children.Add(new XLabel
                           {
                               FontSize = FontSizes.Standard17,
                               VerticalOptions = LayoutOptions.CenterAndExpand,
                               HorizontalOptions = LayoutOptions.Start,
                               VerticalTextAlignment = TextAlignment.Center,
                               Margin = new Thickness
                                        {
                                            Left = Sizes.FormItemLeftPadding
                                        }
                           }.Export(out DocumentName), 0, 1);
         Grid.SetColumnSpan(DocumentName, 3);
         grid.Children.Add(new XLabel
                           {
                               FontSize = FontSizes.Standard17,
                               VerticalOptions = LayoutOptions.CenterAndExpand,
                               VerticalTextAlignment = TextAlignment.Center,
                               Margin = new Thickness
                                        {
                                            Left = Sizes.FormItemLeftPadding
                                        }
                           }.Export(out Date), 0, 2);
         grid.Children.Add(new XLabel
                           {
                               FontSize = FontSizes.Standard17,
                               VerticalOptions = LayoutOptions.CenterAndExpand,
                               VerticalTextAlignment = TextAlignment.Center,
                               Margin = new Thickness
                                        {
                                            Left = Sizes.FormItemLeftPadding
                                        }
                           }.Export(out Sum), 0, 3);
         Grid.SetColumnSpan(Sum, 3);
         grid.Children.Add(new Switch().Export(out RelationshipSwitch), 2, 1);
         grid.Children.Add(new Label
                           {
                               FontSize = FontSizes.DashboardCellText,
                               VerticalOptions = LayoutOptions.End,
                               HorizontalOptions = LayoutOptions.StartAndExpand,
                               VerticalTextAlignment = TextAlignment.Center,
                               TextColor = Colors.TextDisableColor,
                               Margin = new Thickness
                                        {
                                            Left = Sizes.FormItemLeftPadding
                                        },
                               IsVisible = false
                           }.Export(out Remainder), 0, 4);
         Grid.SetRowSpan(RelationshipSwitch, 4);
         Grid.SetColumnSpan(Remainder, 4);
         grid.Children.Add(new Divider().Export(out middleDivider), 0, 5);
         Grid.SetColumnSpan(middleDivider, 4);
         grid.Children.Add(new Entry{Keyboard = Keyboard.Numeric}.Export(out inputSum), 0, 6);
         Grid.SetColumnSpan(inputSum, 4);
         grid.Children.Add(new Divider
                           {
                               VerticalOptions = LayoutOptions.EndAndExpand,
                               FullWidth = true
                           }.Export(out bottomDivider), 0, 7);
         Grid.SetColumnSpan(bottomDivider, 4);
         grid.BackgroundColor = Color.White;
         Children.Add(grid);
         if (hasBottomButton)
             Children.Add(new PaymentBillRelationFooter(textForButton, goToCreateMoney));
         GestureRecognizers.Add(new TapGestureRecognizer
                                {
                                    Command = new Command(() => RelationshipSwitch.IsToggled = !RelationshipSwitch.IsToggled)
                                });
    
         RelationshipSwitch.IsToggled = hasRelation;
         inputSum.IsVisible = hasRelation;
         middleDivider.IsVisible = hasRelation;
         RelationshipSwitch.Toggled += (_, __) => ChangeRelation();
         if (isShowRemainder)
         {
             Remainder.IsVisible = true;
             middleDivider.SetValue(Grid.RowProperty, 5);
             inputSum.SetValue(Grid.RowProperty, 6);
             RelationshipSwitch.SetValue(Grid.RowSpanProperty, 4);
         }
         else
         {
             Remainder.IsVisible = false;
             middleDivider.SetValue(Grid.RowProperty, 6);
             inputSum.SetValue(Grid.RowProperty, 7);
             RelationshipSwitch.SetValue(Grid.RowSpanProperty, 3);
         }
     }
    
     private LightStackLayout GetTopBoldDivider()
     {
         return new LightStackLayout
                {
                    Children =
                    {
                        new Divider(Colors.LightGrayDivider)
                        {
                            VerticalOptions = LayoutOptions.End,
                            FullWidth = true,
                            HeightRequest = 16,
                        },
                        new Divider
                        {
                            VerticalOptions = LayoutOptions.End,
                            FullWidth = true
                        }
                    }
                };
     }
    
     protected override void OnBindingContextChanged()
     {
         base.OnBindingContextChanged();
    
         var data = (PaymentBillRelationViewData) BindingContext;
         if (data == null)
             return;
    
         SetData(data);
     }
    
     private void SetData(PaymentBillRelationViewData item)
     {
         if (isShowRemainder)
             Remainder.Text =
                 $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
    
         if (inputSum.IsVisible)
             inputSum.Text = item.ConnectedSumToCurrentDoc != 0
                                 ? item.ConnectedSumToCurrentDoc.ToString()
                                 : "";
    
         inputSum.TextChanged += (_, __) => ChangeRelatedSum();
    
         DocumentName.Text = item.DocumentName;
         Date.Text = item.DateOfDocument;
         Sum.Text = $"{item.AllAmountMoney.FormatMoneyWithCoopeks()} {MoneyHelpers.RubleSumbol}";
     }
    
     private void ChangeRelatedSum()
     {
         var item = (PaymentBillRelationViewData) BindingContext;
         if (item == null)
             return;
    
         decimal? inputSum = null;
         try
         {
             if (this.inputSum.Text.Length > 0)
                 inputSum = decimal.Parse(this.inputSum.Text);
         }
         catch (Exception e)
         {
         }
    
         changeRelationAmount?.Invoke(item, inputSum);
         if (isShowRemainder)
             Remainder.Text =
                 $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
         var textError = checkRelationForError?.Invoke(item);
         if (textError.Length > 0)
         {
             bottomDivider.BackgroundColor = Color.Red;
         }
         else
         {
             bottomDivider.BackgroundColor = Colors.Divider;
         }
    
         updateHeader?.Invoke();
         makeVisible?.Invoke(item);
     }
    
     private void ChangeRelation()
     {
         var item = (PaymentBillRelationViewData) BindingContext;
         if (inputSum.IsVisible == RelationshipSwitch.IsToggled)
             return;
         inputSum.IsVisible = RelationshipSwitch.IsToggled;
         middleDivider.IsVisible = RelationshipSwitch.IsToggled;
         changeRelationStatus?.Invoke(item, RelationshipSwitch.IsToggled);
         inputSum.Text = RelationshipSwitch.IsToggled ? item.ConnectedSumToCurrentDoc.ToString() : "";
         if (isShowRemainder)
             Remainder.Text =
                 $"Осталось связать: {calculateRelationRemainder?.Invoke(item)} {MoneyHelpers.RubleSumbol}";
         updateHeader?.Invoke();
         if (RelationshipSwitch.IsToggled)
             makeVisible?.Invoke(item);
     }
    

    }

  • LandLuLandLu Member, Xamarin Team Xamurai

    @zoyusibu I still can't run the code above on my side as it contains the unknown model like PaymentBillRelationViewData. We can't accurately find out your issue without your sample.
    However, the collection view renders to UICollectionView on iOS. Its ContentInset and ContentOffset may be changed when you resize the cell. Try to add a custom renderer for your custom collection view and then reset the properties when the automatic scrolling happens.

  • zoyusibuzoyusibu Member ✭✭

    @LandLu said:
    @zoyusibu I still can't run the code above on my side as it contains the unknown model like PaymentBillRelationViewData. We can't accurately find out your issue without your sample.
    However, the collection view renders to UICollectionView on iOS. Its ContentInset and ContentOffset may be changed when you resize the cell. Try to add a custom renderer for your custom collection view and then reset the properties when the automatic scrolling happens.

    Ok, i will try.

    PaymentBillRelationViewData:

    public class PaymentBillRelationViewData
    {
    public Guid Id { get; set; }
    public KdrLine KdrLine { get; set; }
    public DocumentViewData DocumentViewData { get; set; }
    public string DocumentName { get; set; }
    public string DateOfDocument { get; set; }
    public decimal? ConnectedSumToCurrentDoc { get; set; }
    public decimal AllConnectedMoney { get; set; }
    public decimal? AllAmountMoney { get; set; }
    public bool HadRelationWithCurrentDoc { get; set; }
    public decimal? OldValueAllConnectedMoney { get; set; }
    }

  • zoyusibuzoyusibu Member ✭✭

    @LandLu said:
    However, the collection view renders to UICollectionView on iOS. Its ContentInset and ContentOffset may be changed when you resize the cell. Try to add a custom renderer for your custom collection view and then reset the properties when the automatic scrolling happens.

    Please tell me how I can determine when the list scrolls up programmatically, and when the user?

  • LandLuLandLu Member, Xamarin Team Xamurai

    The easiest way to achieve it is MessagingCenter. Create your custom renderer for your collection view like:

    [assembly: ExportRenderer(typeof(CollectionView), typeof(CustomCollectionViewRemderer))]
    namespace App.iOS
    {
        public class CustomCollectionViewRemderer : CollectionViewRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> e)
            {
                base.OnElementChanged(e);
    
                if (Control != null)
                {
                    MessagingCenter.Subscribe<object, object>(this, "InsetChanged", (sender, args) =>
                    {
                        ((UICollectionView)NativeView.Subviews[0].Subviews[0]).ContentInset = new UIEdgeInsets(0, 0, 0, 0);
                        ((UICollectionView)NativeView.Subviews[0].Subviews[0]).ContentOffset = new CoreGraphics.CGPoint(0, 0);
                    });
                }
            }
        }
    }
    

    Trigger this messaging center when you toggle the switch:

    MessagingCenter.Send<object, object>(this, "InsetChanged", object);
    
  • zoyusibuzoyusibu Member ✭✭
    edited July 9

    @LandLu
    unfortunately it doesn't work because i can't calculate the correct ContentOffSet, because each time the expandable cell shifts to an unknown position.

    video example: https://drive.google.com/file/d/1mImRsSciBGZOgMd2dSDNCd8H476-_HEv/view?usp=sharing

    code custom renderer:

    public class CustomCollectionViewRenderer: CollectionViewRenderer
    {
    private nfloat oldValueOffset = 0;
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);
    if (Control == null)
    return;
    ((UICollectionView)NativeView.Subviews[0].Subviews[0]).Delegate = new MyDelegate(this);
    MessagingCenter.Subscribe<object, object>(this, "InsetChanged", (sender, args) =>
    {
    ((UICollectionView)NativeView.Subviews[0].Subviews[0]).ContentInset = new UIEdgeInsets(0, 0, 0, 0);
    ((UICollectionView)NativeView.Subviews[0].Subviews[0]).ContentOffset = new CoreGraphics.CGPoint(0, oldValueOffset);
    });
    }

     private void Scrolled(nfloat nfloat)
     {
         oldValueOffset = nfloat;
     }
    
     public class MyDelegate: UIKit.UICollectionViewDelegate
     {
         private readonly CustomCollectionViewRenderer renderer;
    
         public MyDelegate(CustomCollectionViewRenderer renderer)
         {
             this.renderer = renderer;
         }
         public override void Scrolled(UIScrollView scrollView)
         {
             renderer.Scrolled(scrollView.ContentOffset.Y);
         }
     }
    

    }

  • zoyusibuzoyusibu Member ✭✭
    edited July 10

    @LandLu
    i tried this is the solution to my problem, bur it's work if collectionview has few items

    public class CustomCollectionViewRenderer: ItemsViewRenderer
        {
            private nfloat oldValueOffset = 0;
            private bool lockOldValue;
    
            protected override void OnElementChanged(ElementChangedEventArgs<ItemsView> e)
            {
                base.OnElementChanged(e);
                if (Control == null)
                    return;
    
    
                NSArray s = Control.ValueForKey(new NSString("_subviewCache")) as NSMutableArray;
                UICollectionView collectionView = s.GetItem<UICollectionView>(0);
                collectionView.Delegate = new CustomCollectionViewDelegate(this);
    
                MessagingCenter.Subscribe<object, object>(this, "InsetChanged",
                                                          async (sender, args) =>
                                                          {
                                                              lockOldValue = true;
                                                              await Task.Delay(10);
                                                              collectionView.ContentOffset =
                                                                  new CGPoint(0, oldValueOffset);
                                                              lockOldValue = false;
                                                          });
            }
    
            private void Scrolled(nfloat nfloat)
            {
                if (!lockOldValue)
                    oldValueOffset = nfloat;
            }
    
            private class CustomCollectionViewDelegate: UICollectionViewDelegate
            {
                private readonly CustomCollectionViewRenderer renderer;
    
                public CustomCollectionViewDelegate(CustomCollectionViewRenderer renderer)
                {
                    this.renderer = renderer;
                }
    
                public override void Scrolled(UIScrollView scrollView)
                {
                    renderer.Scrolled(scrollView.ContentOffset.Y);
                }
            }
        }
    
  • zoyusibuzoyusibu Member ✭✭

    please help me anybody :(

  • LandLuLandLu Member, Xamarin Team Xamurai

    @zoyusibu If you want me to help you look into this issue you'd better create a sample and post it here. Or I can't reproduce the same issue you are facing. And I can only offer a general answer.

  • zoyusibuzoyusibu Member ✭✭

    @LandLu said:
    @zoyusibu If you want me to help you look into this issue you'd better create a sample and post it here. Or I can't reproduce the same issue you are facing. And I can only offer a general answer.

    Sorry, but I do not know how to create a project with samples. I can only show separate pieces of code from the project in which I work

  • LandLuLandLu Member, Xamarin Team Xamurai

    @zoyusibu Grab the single page to a new project. Remove all the dependencies and use the simple control to reproduce your issue with the new project. Then we can help you analyze your issues and find out an appropriate workaround.

  • zoyusibuzoyusibu Member ✭✭

    @LandLu said:
    @zoyusibu Grab the single page to a new project. Remove all the dependencies and use the simple control to reproduce your issue with the new project. Then we can help you analyze your issues and find out an appropriate workaround.

    @LandLu
    I was able to reproduce it.
    I noticed that the problem occurs if the first cell has a different size

  • zoyusibuzoyusibu Member ✭✭

    @LandLu
    did you see the bug?

  • LandLuLandLu Member, Xamarin Team Xamurai

    @zoyusibu Collection view is still in preview and we can't help you further: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/
    But I think ListView can fit your requirement after seeing your sample if you only need vertical view cell. So I created a sample for you and hoped it could solve your problem temporarily.
    If you do want to know why this occurs on Collection View you could open a support ticket here: https://support.microsoft.com/en-us/supportforbusiness/productselection?sapId=211dd84f-3474-c3c5-79bf-66db630c92a6

Sign In or Register to comment.