如何设置uicollectionview布局 初始偏移

如何设置UICollectionView 初始偏移_百度知道
如何设置UICollectionView 初始偏移
- 如何设置UICollectionView 初始偏移 如题,我希望能够在进入UICollectionViewController的时候,collectionView的内容就已经滚动到我需要的位置
Android|HTML5|VR培训名师面授
主营:Android培训、HTML5培训、VR培训、iOS培训
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁[ios]动画中的 UICollectionView UITableView 局部的偏移量会导致过早地消失的单元格
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.
我们有 UICollectionView 用自定义布局非常类似于 UITableView (它垂直滚动)。UICollectionView 显示只有 3 单元格同时,其中之一是当前活动单元格:
(活动单元格在这里是 #2)。单元格是大约 280 点高,所以只有活动单元格是在屏幕上完全可见。用户不会直接滚动视图来导航,相反,她刷的活动单元格水平以前进到下一个单元格。做一些花哨的动画,然后滚动 UICollectionView,以便下一个单元格是在"积极"的位置,从而使它的活跃的一个,搬走旧和养育在队列中的下一个单元格:
这里的问题,设置 UICollectionView 的偏移量。我们目前正在将其设置在 UIView 的动画块 ( self.collectionView.contentOffset = targetO ) 以及三个其他属性进行动画处理,其中大多是很有效,但起因的第一个单元格 (以前的活动中的一个,后者的情况下,#2) 尽快动画开始运行,甚至在延迟间隔完成之前的消失。这绝对不是理想。
我想到的一些解决办法,但不能找出最好的一个:
荒谬的是放大 UICollectionView 的框架,以适应而不是三个,迫使它保存在内存中的单元格,即使他们是屏幕外的五个单元格。我试过和有用的但它听起来像太脏的黑客。
快照的消失的单元格的呈现内容,把它放在 UIImageView 中,添加 UIImageView 作为子的只是在该单元格之前局部视图就会消失的确切的同一位置的旧的单元格,删除它一旦在动画结束。听起来不那么烂比前面的选项 (memory-wise,至少),但仍有点的出租司机。我也不知道的最好的方式来实现此目的,请点我正确的方向。
切换到 UIScrollView 的 setContentOffset:animated: 。我们其实曾经有这一点,和它固定的消失的单元格问题,但显然与其他 UIView 动画并行运行这争夺主线程,从而创造一个非常波浪起伏的动画单核心设备 (iPhone 3GS/4) 上的注意。它也不允许我们改变持续时间或宽松的动画,因此让人感觉与其余部分不同步。还是一个选项如果我们可以找到办法,使其工作在 UIView 块动画与和谐。
切换到 UICollectionView 的 scrollToItemAtIndexPath:atScrollPosition:animated: 。没有试过,但它有一个大的缺点: 它只需 3 可能的常数 (适用于此情况下,至少) 目标滚动位置为: UICollectionViewScrollPositionTop , UICollectionViewScrollPositionCenteredVertically 和 UICollectionViewScrollPositionBottom 。活动单元格可能会发生变化其高度,但它总是要 35 点从窗口的顶部,这些选项不提供足够的控制来完成设计。它还可能有 3.1 正疑难。选项仍然因为可能有一个方法去周围的滚动位置的事情我不知道的并且它可能不具有与主线程,似乎不太可能同样的问题。
任何帮助将不胜感激。请问是否你需要澄清。多谢!
解决方法 1:
我和一起 #2。在这里是不会呈现和存储的代码段:
UIGraphicsBeginImageContext(theCell.bounds.size);
[theCell.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *renderedCellImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
该方法的其余部分几乎是,因为有一点需要注意上文所述: 这必须做,并且图像实际上用之前在一个后台线程,因为渲染可以带达 1 全第二次在 iPhone 4 上。希望这可以帮助别人。UICollectionView在初始化的时候移动到某个距离
#pragma mark -- 使用场景:选中非第一张图片用CollectionView进行浏览时,CollectionView滑动到相应的位置
#pragma mark -- 重点在于UICollectionViewFlowLayout的prepareLayout方法的使用
#pragma mark -- 自定义UICollectionViewFlowLayout的h文件
@interface SSCollectionViewFlowLayout : UICollectionViewFlowLayout
* collectionView的偏移量
@property (nonatomic, assign) CGP
#pragma mark -- 自定义UICollectionViewFlowLayout的m文件
@implementation SSCollectionViewFlowLayout
- (instancetype)init{
self = [super init];
if (self) {
self.scrollDirection = UICollectionViewScrollDirectionH
- (void)prepareLayout{
[super prepareLayout];
self.collectionView.contentOffset = self.
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)oldBounds{
return NO;
#pragma mark -- 剩下的工作就是在UICollectionView 所在的ViewController设置偏移量
@property (nonatomic, strong) SSCollectionViewFlowLayout *viewL
@property (nonatomic, strong) UICollectionView *ssCollectionV
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.ssCollectionView.frame = CGRectMake(0.f, 0.f, ScreenWidth, ScreenHeight);
self.viewLayout.offsetpoint = CGPointMake(ScreenWidth *self.indexNumber, 0.f);
- (UICollectionView *)ssCollectionView{
if (_ssCollectionView != nil) {
return _ssCollectionV
self.viewLayout = [[SSCollectionViewFlowLayout alloc] init];
_ssCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.viewLayout];
_ssCollectionView.showsHorizontalScrollIndicator = FALSE; // 去掉滚动条
_ssCollectionView.pagingEnabled = YES;
_ssCollectionView.delegate =
_ssCollectionView.dataSource =
[_ssCollectionView registerClass:[CustomCollectionViewCell class] forCellWithReuseIdentifier:@CollectionCell];
return _ssCollectionV
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'下次自动登录
关注移动互联网和移动APP开发工具、开发框架、测试工具、微信开发、Android源码、Android开源类库以及各种开源组件的IT科技网站
现在的位置:
关于自定义UICollectionViewLayout的一点个人理解
自定义UICollectionView,主要会用到以下几个方法:
- (void)prepareL 第一次加载layout、刷新layout、以及- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newB这个方法返回yes时,会调用。这是苹果官方的说明The collection view calls -prepareLayout once at its first layout as the first message to the layout instance. The collection view calls -prepareLayout again after layout is invalidated and before requerying the layout information. Subclasses should always call super if they override。实现该方法后应该调用[super prepareLayout]保证初始化正确。该方法用来准备一些布局所需要的信息。该方法和init方法相似,但该方法可能会被调用多次,所以一些不固定的计算(比如该计算和collectionView的尺寸相关),最好放在这里,以保证collectionView发生变化时,自定义CollectionView能做出正确的反应。
- (nullable NSArray&__kindof UICollectionViewLayoutAttributes *& *)layoutAttributesForElementsInRect:(CGRect) 该方法用来返回rect范围内的 cell supplementary 以及 decoration的布局属性layoutAttributes(这里保存着她们的尺寸,位置,indexPath等等),如果你的布局都在一个屏幕内 活着 没有复杂的计算,我觉得这里可以返回全部的属性数组,如果涉及到复杂计算,应该进行判断,返回区域内的属性数组,有时候为了方便直接返回了全部的属性数组,不影响布局但可能会影响性能(如果你的item一屏幕显示不完,那么这个方法会调用多次,当所有的item都加载完毕后,在滑动collectionView时不会调用该方法的)。
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexP 该方法不是必须实现的,即便你实现了,我们对collectionView的任何操作,也不会导致系统主动调用该方法。该方法通常用来定制某个IndexPath的item的属性。当然我们也可以重写这个方法,将布局时相关的属性设置放在这里,在- (nullable NSArray&__kindof UICollectionViewLayoutAttributes *& *)layoutAttributesForElementsInRect:(CGRect)rect 或者 - (void)prepareLayout 中 需要创建用来返回给系统的属性数组 主动调用这个方法,并添加带可变数组中去返回给系统。当然我们也可以在 - (void)prepareLayout 中 通过[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]] 获取 每个indexPath的attributes,在- (void)prepareLayout中设置所有item的属性。看需求以及个人喜欢。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newB 用来刷新layout的,当我们返回yes的时候。如果我们的需求不需要实时的刷新layout,那么最好判断newBounds 和 我们的collectionView的bounds是否相同,不同时返回yes;(例如苹果官方的lineLayout,因为每次滑动都要放大item,所以这了就直接返回yes)。
以苹果官方的lineLayout为例,这个是对UICollectionViewFlowLayout的扩充,
self = [super init];
if (self) {
self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
self.scrollDirection = UICollectionViewScrollDirectionH
self.sectionInset = UIEdgeInsetsMake(200, 0.0, 200, 0.0);//上下边距
self.minimumLineSpacing = 50.0;//行间距
这里初始化一些信息。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
return YES;
因为滑动放大,故这里需要返回yes,实时刷新layout。
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
NSArray* array = [super layoutAttributesForElementsInRect:rect];
//可视rect
CGRect visibleR
visibleRect.origin = self.collectionView.contentO
visibleRect.size = self.collectionView.bounds.
//设置item的缩放
for (UICollectionViewLayoutAttributes* attributes in array) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;//item到中心点的距离
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;//距离除以有效距离得到标准化距离
//距离小于有效距离才生效
NSLog(@"%f",distance);
if (ABS(distance) & ACTIVE_DISTANCE) {
CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));//缩放率范围1~1.3,与标准距离负相关
attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);//x,y轴方向变换
//attributes.zIndex = 0;
这里对item进行放大操作(因为该类是继承自UICollectionViewFlowLayout,苹果重写了该方法,所以调用super可以拿到当前rect范围内attributes,如果继承自UICollectionViewLayout,调用super是什么都拿不到的)。这里的思想就是:距离屏幕中心超过一定距离(假设200,自己设定)开始放大,CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;item中心到屏幕中心点距离占200的比例,
CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
这样便得到放大的倍数。
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
//proposedContentOffset是没有对齐到网格时本来应该停下的位置
//计算出实际中心位置
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);
//取当前屏幕中的UICollectionViewLayoutAttributes
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray* array = [super layoutAttributesForElementsInRect:targetRect];
//对当前屏幕中的UICollectionViewLayoutAttributes逐个与屏幕中心进行比较,找出最接近中心的一个
for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) & ABS(offsetAdjustment)) {
offsetAdjustment = itemHorizontalCenter - horizontalC
//返回调整好的point
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity 这个方法简单理解可以当作是用来设置collectionView的偏移量的,计算当前屏幕哪个item中心点距离屏幕中心点近,就将该item拉到中心去。
个人理解,不对的地方还请见谅。
【上篇】【下篇】如何设置UICollectionView 初始偏移_百度知道
如何设置UICollectionView 初始偏移
提问者采纳
只有两个以上的输出才有相位的偏移用错了吧,没有偏移的说法,对单个信号来说,因为不能跟自己偏移
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 tableview设置偏移量 的文章

 

随机推荐