(参照点是:父亲的坐标系统) origin是frame或bounds的左上角坐标 contentInset和contentOffset contentSize是contentView的大小 contentInset 中的padding,是view相对于子view的距离有四个属性 例如UIEdgeInsets(top: 10.0, left: 20.0, bottom: 30.0, right: 40.0) contentOffset UIEdgeInsets(top: 10.0, left: 20.0, bottom: 30.0, right: 40.0), 那么 scrollViewA的bounds为(-20,-10) scrollViewA的contentOffset 为(-20,-10) 在scrollViewA的内容滚动时contentSize是不变的 contentInset也是不变的 变得只是contentOffset和bounds 并且contentOffset 和bounds的值是一样的 上拉y变大,下拉y变小 左拉x变大,右拉x变小 可以这样想以scrollViewA的左上角为坐标系原点y轴向上为正,x轴向左为正,那么contentOffset和bounds
headerView: 添加在vc.view上,置顶,其高度根据mainScrollView.contentOffset.y计算出来,使其正好贴在tabContainerView上。 (offset) { return } scrollView.contentOffset = offset;}---6.3、mainScrollView的滑动回调:public scrollView.isEqual(self.currentSubScrollView) { return } if scrollView.contentOffset.y.isEqual (to: self.subScrollViewPreOffset.y) { return } let pullDown: Bool = scrollView.contentOffset.y return } self.mainScrollEnable = true if scrollView.contentOffset.y <= 0 { /// 忽略下拉刷新的回弹
override var contentOffset: CGPoint { didSet { if contentOffset.y ! 下层滑动 } //同步offset到上下文 syncScrollContext.outerOffset = contentOffset } } } } 上层的scrollView的contentOffset变化时计算: class TopScrollView: UITableView override var contentOffset: CGPoint { didSet { if contentOffset.y ! } //不管怎么样,滑动即同步offset到上下文 syncScrollContext.innerOffset = contentOffset
= 0) { scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, 0); } NSLog(@"scroll %f",scrollView.contentOffset.x); self.topExcelCollectionView.contentOffset = scrollView.contentOffset; for (ExcelTableCell* cell in self.excelTableView.visibleCells = scrollView.contentOffset; self.cacheContentOffset = CGPointMake(scrollView.contentOffset.x , scrollView.contentOffset.y); } } } }else{
<200) { scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y +10*400); }else if(scrollView.contentOffset.y>11*400){ scrollView.contentOffset = CGPointMake (scrollView.contentOffset.x, scrollView.contentOffset.y-10*400); } if (scrollView.contentOffset.x <160) { scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x+10*320,scrollView.contentOffset.y ); }else if(scrollView.contentOffset.x>11*320){ scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x
frame, to: self.view) UIView .animate(withDuration: 0) { let contentOffset = self.topScroll contentOffset; //选中栏目的最前几个:scrollView偏移值 + 那个按钮的X值 <= 当前显示窗口中间X值 if contentOffset.x < setContentOffset(CGPoint(x:0,y:contentOffset.y), animated: true) //(self.ScreenWidth/2 - setContentOffset(CGPoint(x:contentOffset.x - (self.ScreenWidth/2 - rect.origin.x - self.titleWidth/2) ,y:contentOffset.y), animated: true) } } } 现在,点击任意一个栏目,栏目(按钮)的背景色都会变成橙色,而上一个选中的栏目会变成原来的灰色
禁用tableView和webView.scrollVie的scrollEnabled = NO,通过添加pan手势,手动调整 contentOffset。 禁用tableView和webView.scrollVie的scrollEnabled = NO,通过添加pan手势,手动调整contentOffset。 self.contentView.sl_y = offsetY; self.webView.scrollView.contentOffset = CGPointMake = CGPointMake(0, _webViewContentHeight - webViewHeight); self.tableView.contentOffset = CGPointZero (0, offsetY - _webViewContentHeight); self.webView.scrollView.contentOffset = CGPointMake(0,
的两个代理方法;在前后循环过渡处,刚开始拖拽时就在Bug的位置画上对应的视图;即《 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1》,结束拖拽之后,再改变UIScrollView的contentOffset self.timer = nil; // 3 + 4 + 0 - 1 - 2 - 3 - 4 + 0 + 1 NSInteger index = scrollView.contentOffset.x (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ NSInteger index = scrollView.contentOffset.x [self statrScroll:_second]; } //是为了解决循环滚动的连贯性问题 if (index == 0) { scrollView.contentOffset } } - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ CGFloat index = scrollView.contentOffset.x
UITableView UICollectionView UITextView 1.3 UIScrollView常见的重要属性 属性名 作用 contentSize 设置UIScrollView的滚动范围 contentOffset *)scrollView 缩放完成时调用的方法 - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView 2 三个重要属性的进一步加强contentOffset ,contentSize, contenInset 2.1 contentOffset scrollView 通过修改 contentOffset 调整内部视图的坐标位置,从而给用户产生一种视觉上的滚动的效果 contentOffset 的值本质上就是 bounds 的原点(origin) 值,苹果在为了方便程序员的理解,增加了这个属性 文档释义:contentOffset:内容视图原点(origin)所在的偏移位置 scrollView 通过修改 contentInset 调整内部和边缘的偏移 设置边距之后,初始没有效果,需要拖拽一下才有效果 可以通过设置 contentOffset 调整初始位置 contengInset
:scrollView.contentOffset) self.startInfo = trackerInfo } } func trackerDidEndDragging :scrollView.contentOffset) self.endInfo = trackerInfo if decelerate == false :scrollView.contentOffset) self.endInfo = trackerInfo logSlideSkipObserve contentOffset ?? .zero) == \(endInfo?.contentOffset ?? contentOffset.y ?? 0 < endInfo?.contentOffset.y ??
scrollView == self.tableView) { CGFloat sectionHeaderHeight = 12; if (scrollView.contentOffset.y <=sectionHeaderHeight&&scrollView.contentOffset.y>=0) { scrollView.contentInset = UIEdgeInsetsMake (-scrollView.contentOffset.y, 0, 0, 0); } else if (scrollView.contentOffset.y>=sectionHeaderHeight
contentOffset是scrollView实际滚动区域的左上角与视图可视区域左上角的距离。 pagingEnabled是是否以一页的大小整体进行滚动,也就是用来实现翻页的效果。 UIScrollView的一些常用的代理方法如下: #pragma mark - UIScrollViewDelegate //监听页面滚动,根据scrollView.contentOffset来做业务逻辑 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // NSLog(@"%f, %f", scrollView.contentOffset.x , scrollView.contentOffset.y); } //开始拖拽。
UIScrollView) { //因为可以左右滑,所以不能简单地加1,而要通过contentofff计算要滑到第几张图片 let page = Int(scrollView.contentOffset.x / width) if page == 0 { scrollView.contentOffset.x = width * CGFloat(imageCount) } else if page == imageCount + 1 { scrollView.contentOffset.x = width } pageCtrl.currentPage = Int(scrollView.contentOffset.x / width) - 1 } } 上面说的主要是对手势滑动部分的处理 = width page = 0 } else { self.scrollView.contentOffset.x = self.width * CGFloat
其原因是无论是分页滚动还是不分页滚动,在滚动时都是通过调整滚动视图的contentOffset来实现的。 而当滚动视图进行横竖屏切换时不会调整对应的contentOffset值,这样就导致了在屏幕方向切换时的滚动位置出现异常。 解决的办法就是在屏幕滚动时的相应回调处理方法中修正这个contentOffset的值来解决这个问题。 调整到正确的contentOffset int pageIndex = scrollView.contentOffset.x / scrollView.frame.size.width; = CGPointMake(pageIndex * scrollView.frame.size.width, scrollView.contentOffset.y); }
RxSwift 实现代理 scrollView 代理 override func viewDidLoad() { super.viewDidLoad() scrollView.rx.contentOffset .subscribe(onNext: { contentOffset in print("contentOffset: \(contentOffset)")
UIScrollView *)scrollView{ if (scrollView.tag == 0){ //NSLog(@"viewdisscroll length %f",scrollView.contentOffset.x ); int pageNumber = floor(scrollView.contentOffset.x / 320 + 0.5) +1; //NSLog(@"page scrollView.tag); if (scrollView.tag == 0){ //NSLog(@"viewdisscroll length %f",scrollView.contentOffset.x ); int pageNumber = floor(scrollView.contentOffset.x / 320 + 0.5) +1; //NSLog(@"page
if (scrollView == self.tableView) { CGFloat sectionHeaderHeight = 10; if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) { scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0); } else if (scrollView.contentOffset.y sectionHeaderHeight = 64; CGFloat sectionFooterHeight = 120; CGFloat offsetY = tableview.contentOffset.y
sender: UIPageControl) { let contentOffsetX = bannerW * CGFloat(sender.currentPage) let contentOffset = CGPoint(x: contentOffsetX, y: 0) scrollView.setContentOffset(contentOffset, animated: true scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let contentOffsetX = scrollView.contentOffset.x
顶部视图确实是直接作为self.view的子视图来添加的,但是列表的范围同样是覆盖整个屏幕,那么为了避免列表内容被顶部视图盖住,就要设置列表的contentoffset值。 要注意的是,设置contentoffset值必须在添加列表到self.view之后,否则无效,设置之后可能你会发现刚开始是好的,一点击列表内容就回到顶部了,别慌,那是之后会解决的问题: self.tableView 这里我们利用UIView的一个Delegate:willMoveToSuperview:,它会在我们的视图被添加到父视图上时被调用,在这个代理方法中我们就添加对列表的contentoffset值的观察, 每次这个值变化时就调用处理方法: #pragma mark - UIView Delegate // 在被添加到界面上时就添加对contentoffset的观察 - (void)willMoveToSuperview :(UIView *)newSuperview { [self.headerScrollView addObserver:self forKeyPath:@"contentOffset" options
self.collectionView.frame.size.width/2, self.collectionView.frame.size.height/2+self.collectionView.contentOffset.y <200) { scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y+10*400); //大于最后一屏多一屏 放回第一屏 }else if(scrollView.contentOffset.y>11*400){ scrollView.contentOffset = CGPointMake (0, scrollView.contentOffset.y-10*400); } } 因为咱们的环状布局,上面的逻辑刚好可以无缝对接,但是会有新的问题,一开始运行,滚轮就是出现在最后一个item 的位置,而不是第一个,并且有些相关的地方,我们也需要一些适配: 在viewController中: //一开始将collectionView的偏移量设置为1屏的偏移量 collect.contentOffset