Xamarin iOS UIScrollView с предварительным просмотром следующей / предыдущей страницы: масштаб не работает должным образом - PullRequest
0 голосов
/ 25 октября 2018

У меня есть постраничный UIScrollView, который заполнен коллекцией UIImageViews.Представление прокрутки показывает предварительный просмотр предыдущей и следующей страницы.

Моя цель - сделать каждую страницу в представлении прокрутки масштабируемой.Вот гиф проблемы, с которой я столкнулся, когда другие страницы меняют свои координаты при увеличении изображения:

enter image description here

Я считаю, чтосамо масштабирование приводит к резкому изменению ContentSize вида прокрутки, что исключает все остальное.

Иерархия StoryBoard

[Controller]

---- [UIView]

-------- [UIScrollView], пользовательский класс CapturedResultScrollView

My UIScrollView имеет следующие ограничения для родительского UIView:

enter image description here

Код

Вот реализация CapturedResultScrollView, а также делегат:

public class CaptureResultScrollViewDelegate : UIScrollViewDelegate {
    public CaptureResultScrollViewDelegate(IHandlePaging pageHandler) {
        this.pageHandler = pageHandler ?? throw new ArgumentNullException(nameof(pageHandler));
    }

    private readonly IHandlePaging pageHandler;

    public override UIView ViewForZoomingInScrollView(UIScrollView scrollView) {
        var pageIndex = (int)Math.Round(scrollView.ContentOffset.X / scrollView.Frame.Size.Width);
        return pageHandler.Pages[pageIndex];
    }
}

public interface IHandlePaging {
    UIImageView[] Pages { get; set; }
}

public partial class CaptureResultScrollView : UIScrollView, IHandlePaging {
    public CaptureResultScrollView(IntPtr handle) : base(handle) {
        MinimumZoomScale = 1.0f;
        MaximumZoomScale = 3.0f;
        ZoomScale = 1.0f;
        PagingEnabled = true;
        ClipsToBounds = false;
        ShowsHorizontalScrollIndicator = false;
        ShowsVerticalScrollIndicator = false;
        Delegate = new CaptureResultScrollViewDelegate(this);
    }

    public UIImageView[] Pages { get; set; }

    public void Setup(IList<CapturedResultModel> capturedResults) {
        // setup called from another controller during segue
        Pages = new UIImageView[capturedResults.Count];

        var pageSize = Frame.Size;
        ContentSize = new CGSize(pageSize.Width * Pages.Length, pageSize.Height);

        for (int page = 0; page < capturedResults.Count; page++) {
            var imageView = new UIImageView() {
                // hardcoded value allow for preview of previous/next pages.
                Frame = new CGRect(pageSize.Width * page, 0, pageSize.Width - 30, pageSize.Height),
                ContentMode = UIViewContentMode.ScaleAspectFill,
                Image = UIImage.FromFile(capturedResults[page].ResultImagePath),
                ClipsToBounds = true
            };

            AddSubview(imageView);
            Pages[page] = imageView;
        }
    }
}

Метод Setup CaptureResultScrollView вызывается, когда событие ViewWillAppear содержащего контроллера запускается следующим образом:

public override void ViewWillAppear(bool animated) {
    base.ViewWillAppear(animated);

    CapturedResultScrollView.Setup(CapturedResults);
}

Что я здесь не так делаю?

1 Ответ

0 голосов
/ 26 октября 2018

Причина:

Я думаю, что ваша проблема в том, что вы установили imageView для метода ViewForZoomingInScrollView, когда вы увеличиваете выбранный imageview, только этот imageView увеличит масштаб, и другие изображения ViewView сохранят свои позиции в своем суперпросмотре (здесь ScrollerView), поэтому другие страницы изменяют свои координаты при увеличении изображения.

  public override UIView ViewForZoomingInScrollView(UIScrollView scrollView) {
        var pageIndex = (int)Math.Round(scrollView.ContentOffset.X / scrollView.Frame.Size.Width);
        return pageHandler.Pages[pageIndex];
    }

Решение:

Мой совет заключается в том, что вы можете добавить представление, которое имеет ту же рамку с ScrollView, что и суперпредставление imageView.И установите в этом представлении значение, возвращаемое методом ViewForZoomingInScrollView вместо imageView, поэтому при увеличении этого представления imageViews будет масштабироваться правильно.

Вот мой код:

1.Добавьте backView в ваш IHandlePaging интерфейс

 public interface IHandlePaging
    {
        UIImageView[] Pages { get; set; }

        UIView backView { get; set; }

    }

2. Добавьте этот backView в ScrovllView и добавьте ImageViews к этому backView

 public void Setup(IList<CapturedResultModel> capturedResults)
        {

            Pages = new UIImageView[capturedResults.Count];
            var pageSize = Frame.Size;
            ContentSize = new CGSize(pageSize.Width * Pages.Length, pageSize.Height);

            backView = new UIView()
            {
               //set the backView's size same as scrollview's contentSize
                Frame = new CGRect(15,40,pageSize.Width * capturedResults.Count, pageSize.Height),                
                BackgroundColor = UIColor.Blue,
                ClipsToBounds = true
            };

            Add(backView);

            for (int page = 0; page < capturedResults.Count; page++)
            {       

                var imageView = new UIImageView()
                {

                    Frame = new CGRect( pageSize.Width * page, 0,pageSize.Width - 30, pageSize.Height),                    
                    Image = UIImage.FromBundle(capturedResults[page].ResultImagePath),
                    BackgroundColor = UIColor.Blue,
                    ClipsToBounds = true
                };

                backView.AddSubview(imageView);
                Pages[page] = imageView;

            }
        }

3. Установите backView к методу ViewForZoomingInScrollView возвращаемое значение

  public class CaptureResultScrollViewDelegate : UIScrollViewDelegate
    {
        public CaptureResultScrollViewDelegate(IHandlePaging pageHandler)
        {
            this.pageHandler = pageHandler ?? throw new ArgumentNullException(nameof(pageHandler));
        }

        private readonly IHandlePaging pageHandler;

        public override UIView ViewForZoomingInScrollView(UIScrollView scrollView)
        {
            var pageIndex = (int)Math.Round(scrollView.ContentOffset.X / scrollView.Frame.Size.Width);
            return pageHandler.backView;

        }
    }

4. Наконец, вызовите метод Setup CaptureResultScrollView

public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            IList<CapturedResultModel> CapturedResults = new List< CapturedResultModel >{ new CapturedResultModel { ResultImagePath = "Images1" },
                                                                                          new CapturedResultModel { ResultImagePath = "Images2"},
                                                                                          new CapturedResultModel { ResultImagePath = "Images1" }
                                                                                          };

            CaptureResultScrollView CapturedResultScrollView = new CaptureResultScrollView();
            CapturedResultScrollView.Frame = new CGRect(15, 40, View.Frame.Size.Width - 30, View.Frame.Size.Height-80);
            CapturedResultScrollView.Setup(CapturedResults);
            Add(CapturedResultScrollView);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...