简体   繁体   English

单击时,UIImageView在父级中错误地向上移动

[英]UIImageView erroneously moves up in parent when clicked on

I have an ImageViewController that presents an ImageZoomView (which currently doesn't zoom yet, but it will soon). 我有一个ImageViewController,它提供一个ImageZoomView(当前尚未缩放,但很快就会缩放)。 When I tap on the image, the entire image will shift upwards slightly. 当我点击图像时,整个图像将略微向上移动。 This should not happen, the image should stay in it's place until a user swipes or pinches. 这不会发生,图像应保留在原处,直到用户滑动或捏住为止。

The ImageViewController lives inside a UIPageViewController that allows swiping between views. ImageViewController位于UIPageViewController内部,该UIPageViewController允许在视图之间滑动。 However, the only issue I have is with the ImageViewController (ie the VideoViewController and PdfViewController both work fine and do not shift upwards on a tap) 但是,我唯一遇到的问题是ImageViewController(即VideoViewController和PdfViewController都可以正常工作,并且在轻按时不会向上移动)

ImageZoomView is a UIScrollView with a UIImageView as it's child control. ImageZoomView是一个带有UIImageView作为其子控件的UIScrollView。

ImageZoomView: ImageZoomView:

public class ImageZoomView : UIScrollView
{
    private UIImage _image;
    private UIImageView _imageView;

    public ImageZoomView()
    {
        _imageView = new UIImageView
        {
            ContentMode = UIViewContentMode.ScaleAspectFill
        };

        AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
        ClipsToBounds = true;
        AddSubview(_imageView);
    }

    public int Index { get; set; }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        var imageWidth = Bounds.Width;
        _imageView.Frame = new CGRect(
            Bounds.Left, Bounds.Top,
            imageWidth, imageWidth / _image.Size.Width * _image.Size.Height);

        ContentSize = _imageView.Bounds.Size;
    }

    public void DisplayImage(UIImage image)
    {
        _image = image;
        _imageView.Image = image;
    }
}

ImageViewController: ImageViewController:

public class ImageViewController : AssetViewController
{
    private ImageZoomView _imageView;

    public ImageViewController(int index, Media media) : base(index, media) { }

    public override void ViewDidLayoutSubviews()
    {
        base.ViewDidLayoutSubviews();
        _imageView.Frame = View.Bounds;
    }

    public override void LoadView()
    {
        _imageView = new ImageZoomView()
        {
            Index = Index,
            BackgroundColor = UIColor.White,
        };
        _imageView.DisplayImage((_media as LocalMedia<UIImage>).Resource);
        View = _imageView;
    }
}

AssetViewController: AssetViewController:

public abstract class AssetViewController : UIPageViewController
{
    protected Media _media;

    public AssetViewController(int index, Media media)
    {
        _media = media;
        Index = index;
        View.BackgroundColor = Globals.ColorDark;
    }

    public int Index { get; set; }

    public Media CurrentMedia { get { return _media; } }
}

Few things causing problems 很少有东西会引起问题

  1. All your controllers are derived from UIPageViewController. 您的所有控制器均源自UIPageViewController。 The content controllers should not be derived from UIPageViewController 内容控制器不应从UIPageViewController派生

  2. In ImageViewController the code View = _imageView; 在ImageViewController中,代码View = _imageView; substitutes main View of controller to ScrollView. 将控制器的主视图替换为ScrollView。 I suggest to use AddSubview(_imageView); 我建议使用AddSubview(_imageView); What I saw that this erroneous movement shifts not the scroll view but somehow view of the whole controller. 我所看到的错误动作不是滚动视图,而是整个控制器的视图。

  3. LayoutSubviews is called pretty often and calculates the same thing all the time as neither image size nor scroll bounds are changing. LayoutSubviews经常被调用,并且在图像大小和滚动边界都没有变化的情况下,始终会计算相同的内容。

Below suggested improvements. 以下是建议的改进。

ImageViewController is content controller inside PageViewController and ImageZoomView is the scroll view inside ImageViewController ImageViewController是PageViewController内的内容控制器,ImageZoomView是ImageViewController内的滚动视图

PageViewController PageViewController

public partial class PageViewController : UIPageViewController
{
    public PageViewController(IntPtr handle) : base(handle)
    {
    }

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

        List<ImageViewController> pages = new List<ImageViewController>();
        UIStoryboard board = UIStoryboard.FromName("Main", null);

        for (int i = 0; i < 3; i++)
        {
            ImageViewController ctrl = (ImageViewController)board.InstantiateViewController("imageControllerStoryboardID");
            ctrl.Index = i;
            pages.Add(ctrl);
        }
        DataSource = new PageDataSource(pages);
        View.Frame = View.Bounds;
        //Set the initial content (first page)
        SetViewControllers(new UIViewController[] { pages[0] }, UIPageViewControllerNavigationDirection.Forward, false, s => { });
    }


}

public class PageDataSource : UIPageViewControllerDataSource
{
    List<ImageViewController> pages;

    public PageDataSource(List<ImageViewController> pages)
    {
        this.pages = pages;
    }

    override public UIViewController GetPreviousViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
    {
        var currentPage = referenceViewController as ImageViewController;
        if (currentPage.Index == 0)
        {
            return pages[pages.Count - 1];
        }
        else
        {
            return pages[currentPage.Index - 1];
        }
    }

    override public UIViewController GetNextViewController(UIPageViewController pageViewController, UIViewController referenceViewController)
    {
        var currentPage = referenceViewController as ImageViewController;
        return pages[(currentPage.Index + 1) % pages.Count];
    }
}

ImageViewController ImageViewController

public partial class ImageViewController : UIViewController
{
    public int Index;
    private ImageZoomView _imageView;

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

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

        _imageView = new ImageZoomView(UIImage.FromFile("MergedImage.png"), View.Frame)
        {
            Index = Index,
            BackgroundColor = UIColor.Blue,
        };
        View.AddSubview(_imageView);
    }

}

ImageZoomView ImageZoomView

public class ImageZoomView : UIScrollView
{
    private UIImage _image;
    private UIImageView _imageView;

    public ImageZoomView(UIImage image, CGRect frame):base()
    {
        _imageView = new UIImageView
        {
            ContentMode = UIViewContentMode.ScaleAspectFill,
        };

        _image = image;
        _imageView.Image = image;
        Frame=_imageView.Frame = frame;


        AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
        ClipsToBounds = true;
        AddSubview(_imageView);

        ContentSize = new CGSize(Frame.Width, Frame.Width / _image.Size.Width * _image.Size.Height);
        _imageView.Center = new CGPoint(ContentSize.Width / 2, ContentSize.Height / 2);
    }



    public int Index { get; set; }

}

There are still some code left from original sample as unused Index field and private _image variables. 原始样本中还剩下一些代码,它们是未使用的Index字段和private _image变量。 May be useful in the future, so I kept them around 将来可能会有用,所以我一直在附近

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM