我有一个分页的 UIScrollView,其中填充了一组 UIImageView。 ScrollView 显示上一页和下一页的预览。
我的目标是让 ScrollView 的每一页都可以缩放。这是我遇到的问题的 gif,其中其他页面似乎随着图像的缩放而改变了它们的坐标:
我相信缩放本身会导致 ScrollView 的 ContentSize 发生剧烈变化,这会使其他所有内容都乱七八糟。
Storyboard层次结构
[ Controller ]
---- [UIView]
-------- [UIScrollView], 自定义类 CapturedResultScrollView
我的 UIScrollView
对其父 UIView 有以下约束:
代码
这是 CapturedResultScrollView
实现,以及委托(delegate):
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;
}
}
}
CaptureResultScrollView
的 Setup
方法在包含 Controller 的 ViewWillAppear
事件被触发时被调用,如下所示:
public override void ViewWillAppear(bool animated) {
base.ViewWillAppear(animated);
CapturedResultScrollView.Setup(CapturedResults);
}
我在这里做错了什么?
最佳答案
原因:
我认为你的问题是你为方法 ViewForZoomingInScrollView
设置了你的 imageView
,当你缩放你选择的 imageview
时,只有那个 imageView
将缩放,而其他 imageView 将保持它们在其 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 具有相同框架的 View 作为您的 imageView 的 super View 。并将此 View 设置为方法 ViewForZoomingInScrollView
的返回值而不是 imageView,因此当您缩放此 View 时,imageView 将正确缩放。
这是我的代码:
1.在IHandlePaging
界面中添加一个backView
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.最后调用CaptureResultScrollView
的Setup
方法
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);
}
关于c# - 带有下一页/上一页预览的 Xamarin iOS UIScrollView : Zoom Not Working as Expected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52978363/