Xamarin iOS - UIScrollView 内的 UIImageView 在方向改变后移位

Xamarin iOS - UIImageView inside UIScrollView displaced after orientation change

我动态添加到滚动视图的图像视图有问题。我正在使用 iOS 8 和大小 类 和自动布局。滚动视图已通过故事板添加,我还添加了约束以匹配视图的大小。

挑战在于,动态添加的图像视图开始居中,但在方向改变后,它在滚动视图中移位。

这里有很多解决方案,其中大部分指向重写 ViewWillLayoutSubviews() 函数,然后将 UIImageView 的中心设置到那里的滚动视图。 None 的建议对我有用。每当我旋转设备时,图像视图就会移位。

我试过的一些建议

UIScrollView with centered UIImageView, like Photos app

Center UIImageView inside UIScrollView without contentInset?

这是我添加 UIImageView 的方式。此函数在 ViewDidLoad() 中调用。

public void AddImageInScrollView(int index)
    {
        try
        {
            //Setting up the imageView

            var imageUrl = Items.fetchImages[index]; 

            //Setting up the imageView
            imageView = new UIImageView(); 
       //call method to load the images
            imageView.SetImage(
                url: new NSUrl(imageUrl.AbsoluteUri),
                placeholder: UIImage.FromFile("sample.png"),
                completedBlock: (image, error, type, url) =>
                {
                    imageResizer = new ImageResizer(image);

                    imageResizer.RatioResize(100,100);

                    UIImage resizedImage = imageResizer.ModifiedImage;
                    //when download completes add it to the list
                    Car.images.Add(resizedImage);

                });
            //end method call

            imageView.UserInteractionEnabled = true;
            imageView.ContentMode = UIViewContentMode.ScaleAspectFit;
            imageView.Center = ScrollViewMain.Center;


            //Adding the imageView to the scrollView as subView
            ScrollViewMain.AddSubview(imageView);

          //ScrollViewMain.ContentSize = imageView.Image.Size;
            ScrollViewMain.ContentSize = new CGSize(ScrollViewMain.Frame.Size.Width,ScrollViewMain.Frame.Size.Height);
           catch (Exception ex)
        {

            Console.WriteLine(ex.Message + ex.StackTrace);
        }
    }

ViewWillLayoutSubviews函数

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

        imageView.Frame = new CGRect(0,0,ScrollViewMain.Frame.Size.Width,ScrollViewMain.Frame.Size.Height);

        CenterScrollViewContents ();
    }

CenterScrollViewContents 函数

   public void CenterScrollViewContents()
    {
        try
        {

        var boundsSize = ScrollViewMain.Bounds.Size;

        var contentsFrame = imageView.Frame;

        if (contentsFrame.Size.Width < boundsSize.Width) {

            contentsFrame.X = ((float)boundsSize.Width - (float)contentsFrame.Size.Width) / 2.0f;

        } else {
            contentsFrame.X = 0.0f;
        }

        if (contentsFrame.Size.Height < boundsSize.Height) {

            contentsFrame.Y = ((float)boundsSize.Height - (float)contentsFrame.Size.Height) / 2.0f;

        } else {
            contentsFrame.Y = 0.0f;
        }

        imageView.Frame = contentsFrame;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

    }

旋转后的样例屏幕截图

我设法使用一个简单的解决方案解决了这个问题。我意识到在初始化 imageView 时,我没有将帧大小传递给它的构造函数。有多种方法可以做到这一点,但就我而言,屏幕旋转后,尺寸似乎没有更新。

之前:

        imageView = new UIImageView(); 
        imageView.Frame = new CGRect(0,0,ScrollViewMain.Frame.Size.Width,ScrollViewMain.Frame.Size.Height);

解决方案:

        var frame = new CGRect(0,0,ScrollViewMain.Frame.Size.Width,ScrollViewMain.Frame.Size.Height);
   //Setting up the imageView
        imageView = new UIImageView(frame); 

滚动视图中的图像现在始终居中,即使在方向改变后也是如此。

将您的代码从 ViewWillLayoutSubviews 移至 ViewDidLayoutSubviews。区别在于 ViewWillLayoutSubviews is "Called to notify the view controller that its view is about to layout its subviews." and ViewDidLayoutSubviews"被调用以通知视图控制器它的视图刚刚布置了它的子视图。"

问题是,ScrollViewMain.Frame

{X=0,Y=0,Width=375,Height=667} in ViewWillLayoutSubviews

但是

{X=0,Y=0,Width=667,Height=375} in ViewDidLayoutSubviews

函数看起来像

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();
    ScrollViewMain.ContentSize = new CGSize(ScrollViewMain.Frame.Size.Width, ScrollViewMain.Frame.Size.Height);
    imageView.Frame = new CGRect(0, 0, ScrollViewMain.Frame.Size.Width, ScrollViewMain.Frame.Size.Height);
    CenterScrollViewContents();
}

奖金提示:

您可以使用 imageView.Center = ScrollViewMain.Center; 使视图居中。

如果您有更多时间,请查看 Autolayout constraints。它们为您省去了帧计算的麻烦。