具有下一个/上一个页面预览的Xamarin iOS UIScrollView:缩放无法按预期工作

时间:2018-10-24 21:48:55

标签: c# ios xamarin.ios uiscrollview zoom

我有一个分页的UIScrollView,其中填充了UIImageViews的集合。滚动视图显示上一页和下一页的预览。

我的目标是使滚动视图的每个页面都可缩放。这是我遇到的问题的gif图像,其他页面在缩放图像时似乎会更改其坐标:

enter image description here

我相信缩放本身会导致滚动视图的ContentSize发生巨大变化,从而使其他所有内容都不合时宜。

StoryBoard层次结构

[控制器]

---- [UIView]

-------- [UIScrollView],自定义类CapturedResultScrollView

我的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的{​​{1}}方法:

ViewWillAppear

我在这里做什么错了?

1 个答案:

答案 0 :(得分:1)

原因:

我认为您的问题是您为方法imageView设置了ViewForZoomingInScrollView,当您缩放所选的imageview时,只有imageView会缩放,而其他imageViews将其位置保留在其superView中(此处为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。在您的IHandlePaging界面中添加backView

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

        UIView backView { get; set; }

    }

2。将此backView添加到ScrovllView并将ImageView添加到此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的{​​{1}}方法

CaptureResultScrollView