Ограничения высоты представления не установлены правильно, поскольку я прокручиваю UICollectionView вверх и вниз - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь определить высоту просмотра на основе свойства модели, но при прокрутке UICollectionView вверх и вниз неправильные высоты назначаются видимым ячейкам. Кажется, что установка HeightAnchor в GetCell (то есть cellForItemAtIndexPath) не работает. Как я могу сделать эту работу?

using CoreGraphics;
using Foundation;
using System;
using System.Collections.Generic;
using UIKit;

namespace App2
{
    public partial class ViewController : UIViewController
    {
        private UICollectionView _collectionView;

        public ViewController (IntPtr handle) : base (handle)
        {
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            InitializeCollectionView();
        }

        private void InitializeCollectionView()
        {
            _collectionView = new UICollectionView(View.Frame, new UICollectionViewCompositionalLayout(GetSection()))
            {
                DataSource = new CustomUICollectionViewDataSource(),
                TranslatesAutoresizingMaskIntoConstraints = false
            };

            _collectionView.RegisterClassForCell(typeof(CustomUICollectionViewCell), "CustomUICollectionViewCell");

            View.AddSubview(_collectionView);

            NSLayoutConstraint.ActivateConstraints(new[]
            {
                _collectionView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor),
                _collectionView.BottomAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.BottomAnchor),
                _collectionView.LeftAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeftAnchor),
                _collectionView.RightAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.RightAnchor)
            });
        }

        private static NSCollectionLayoutSection GetSection()
        {
            var size = NSCollectionLayoutSize.Create(NSCollectionLayoutDimension.CreateFractionalWidth(1), NSCollectionLayoutDimension.CreateEstimated(50));
            var item = NSCollectionLayoutItem.Create(size);
            var group = NSCollectionLayoutGroup.CreateHorizontal(layoutSize: size, subitem: item, count: 1);
            var section = NSCollectionLayoutSection.Create(group);

            section.InterGroupSpacing = 5;

            return section;
        }
    }

    public class CustomUICollectionViewDataSource : UICollectionViewDataSource
    {
        private readonly List<Model> _models = new List<Model>
        {
            new Model {Height = 250},
            new Model {Height = 100},
            new Model {Height = 300},
            new Model {Height = 400},
            new Model {Height = 500},
            new Model {Height = 50},
            new Model {Height = 230},
            new Model {Height = 100},
            new Model {Height = 600},
            new Model {Height = 310},
            new Model {Height = 150},
            new Model {Height = 220}
        };

        public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
        {
            var model = _models[(int)indexPath.Item];

            var cell = collectionView.DequeueReusableCell("CustomUICollectionViewCell", indexPath) as CustomUICollectionViewCell;

            cell.UpdateHeight(model.Height);

            return cell;
        }

        public override nint GetItemsCount(UICollectionView collectionView, nint section)
        {
            return _models.Count;
        }
    }

    public sealed class CustomUICollectionViewCell : UICollectionViewCell
    {
        private readonly UIView _uiView;

        [Export("initWithFrame:")]
        public CustomUICollectionViewCell(CGRect frame) : base(frame)
        {
            _uiView = new UIView
            {
                BackgroundColor = UIColor.Brown,
                TranslatesAutoresizingMaskIntoConstraints = false
            };

            ContentView.AddSubview(_uiView);

            NSLayoutConstraint.ActivateConstraints(new[]
            {
                _uiView.TopAnchor.ConstraintEqualTo(ContentView.SafeAreaLayoutGuide.TopAnchor),
                _uiView.BottomAnchor.ConstraintEqualTo(ContentView.SafeAreaLayoutGuide.BottomAnchor),
                _uiView.LeftAnchor.ConstraintEqualTo(ContentView.SafeAreaLayoutGuide.LeftAnchor),
                _uiView.RightAnchor.ConstraintEqualTo(ContentView.SafeAreaLayoutGuide.RightAnchor)
            });
        }

        public void UpdateHeight(int height)
        {
            _uiView.HeightAnchor.ConstraintEqualTo(height).Active = true;
        }
    }

    public class Model
    {
        public int Height { get; set; }
    }
}

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Вот исправление для этого, рекомендованное Поддержка Xamarin :

NSLayoutConstraint heightConstraint;
public void UpdateHeight(int height)
{
    if (heightConstraint == null)
    {
        heightConstraint = _uiView.HeightAnchor.ConstraintEqualTo(height);
        heightConstraint.Active = true;
    }
    else
    {
        heightConstraint.Constant = height;
    }
}
0 голосов
/ 28 октября 2019

Если вы сделаете это, в сообщении для печати будет предложено повторить ограничение.

Вы установили ограничения left, right, bottom, top и добавили ограничение height при обновлении. Первые четыре ограничения уже определили конечную высоту, новая высота здесь не будет работать, и будет напечатано предупреждающее сообщение.

Если вы действительно хотите обновить высоту, вы должны установить ограничения left, right, top, heightс самого начала и сохраните ограничение height, которое используется при обновлении.

var heightConstraint: NSLayoutConstraint?

heightConstraint = _uiView.heightAnchor.constraint(equalToConstant: 50)//Defaults
NSLayoutConstraint.activate([

(_uiView.topAnchor.constraint(equalTo:ContentView.SafeAreaLayoutGuide.topAnchor))!,                
(_uiView.leftAnchor.constraint(equalTo:ContentView.SafeAreaLayoutGuide.leftAnchor))!
(_uiView.rightAnchor.constraint(equalTo:ContentView.SafeAreaLayoutGuide.rightAnchor))!,
(heightConstraint)!
]);

public void UpdateHeight(int height){
    heightConstraint?.isActive = false
    heightConstraint = _uiView.heightAnchor.constraint(equalToConstant: height)
    heightConstraint?.isActive = true
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...