使用内容插入启用的 UIScrollView 分页工作很奇怪
Posted
技术标签:
【中文标题】使用内容插入启用的 UIScrollView 分页工作很奇怪【英文标题】:UIScrollView paging enabled with content inset is working strange 【发布时间】:2013-09-28 13:23:53 【问题描述】:我创建了带有内容插入的 UIScrollView。
scrollView.frame = CGRectMake(-80, 180, 480, 190)
self.scrollView.contentInset = UIEdgeInsetsMake(0, 160, 0, 160);
self.scrollView.pagingEnabled = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
// Add three Views
[self.scrollView addSubview:view1];
[self.scrollView addSubview:view2];
[self.scrollView addSubview:view3];
[view1 setFrame:CGRectMake(0, 0, 160, 190)];
[view2 setFrame:CGRectMake(160, 0, 160, 190)];
[view3 setFrame:CGRectMake(320, 0, 160, 190)];
第一次时,scrollView.contentOffset.x
是 -160.0
但奇怪的问题是当我点击滚动视图(黄色区域)时,内容偏移 x 值重置为 0 并显示如下。
我尝试了几次,但点击滚动视图会将内容偏移重置为 0。
如何防止这种情况发生?
【问题讨论】:
scrollView
的框架是什么?
scrollView.frame = CGRectMake(-80, 180, 480, 190)。我要制作类似的画廊。
【参考方案1】:
UIScrollView
分页通过滚动具有与 scrollView 相同宽度的页面(在您的情况下为 480 宽度的页面)来工作。这意味着您有 1 个单页(由于插入了 160 个内容,您仍然可以左右滚动)。
完成这项工作的一种方法是:
self.scrollView.frame = CGRectMake(80, 180, 160, 190);
self.scrollView.clipsToBounds = NO;
self.scrollView.contentInset = UIEdgeInsetsZero;
self.scrollView.pagingEnabled = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
这将正确地绘制和滚动,但是,屏幕的两侧将无法交互(每侧 80 像素,因为控件从 frame.origin.x=80 开始并在 80+160=240 结束)。
第二种选择是自己处理分页,使用UIScrollViewDelegate
提供的方法。
- (void)viewDidLoad
[super viewDidLoad];
// pageIndex must be declared as a class member - this is used to prevent skipping pages during scroll
pageIndex = 0;
self.scrollView.frame = CGRectMake(0, 180, 320, 190);
self.scrollView.contentInset = UIEdgeInsetsMake(0, 80, 0, 80);
self.scrollView.pagingEnabled = NO;
self.scrollView.clipsToBounds = YES;
[self.scrollView setContentSize:CGSizeMake(480, 190)];
self.scrollView.delegate = self;
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
int pageWidth = 160;
int pageX = pageIndex*pageWidth-scrollView.contentInset.left;
if (targetContentOffset->x<pageX)
if (pageIndex>0)
pageIndex--;
else if(targetContentOffset->x>pageX)
if (pageIndex<3)
pageIndex++;
targetContentOffset->x = pageIndex*pageWidth-scrollView.contentInset.left;
NSLog(@"%d %d", pageIndex, (int)targetContentOffset->x);
【讨论】:
我需要分页和内容插入,因为我想看到内容视图之外的内容。 滚动视图没有单页,因为它有contentInset,它有3页 页面宽度为480
(因为那是你的scrollview)
的宽度;insets
一起320
,小于1页。无论如何,使用contentInset
是不是要走的路,因为它不能很好地进行分页,并且页面不会包含您期望的视图,除非您将每个视图居中在其 480 宽的页面内。
可以看代码,一页宽度=scrollview width(480)-insets(320)=160,内容宽度=480,所以page=3
它不是那样工作的。在pagingEnabled
的文档中说:If the value of this property is YES, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls
。边界不受contentInset
的影响。【参考方案2】:
除了 alex 将 clipsToBounds 设置为 NO 的第一种方法之外,我还需要对滚动视图边界之外的滚动做出反应。所以我创建了 ScrollForwarderView 类,它是 UIView 的子类。
ScrollForwarderView.h
#import <UIKit/UIKit.h>
@interface ScrollForwarderView : UIView
@property (nonatomic, weak) UIScrollView *scrollView;
@end
ScrollForwarderView.m
...
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
if ([self pointInside:point withEvent:event])
return _scrollView;
return nil;
然后将带有自定义类 ScrollForwarderView 的 UIView 放在滚动视图上方,将 scrollView 属性链接到我的滚动视图,它将用户事件很好地转发到滚动视图。
【讨论】:
以上是关于使用内容插入启用的 UIScrollView 分页工作很奇怪的主要内容,如果未能解决你的问题,请参考以下文章
如何在启用分页的情况下实现 UIScrollView 平铺?
如何在启用分页的 UIScrollView 中延迟加载 100 多个页面?
UIScrollView 和 UIImage 在其中启用了分页