zoukankan      html  css  js  c++  java
  • iOS 抖音个人主页布局开发(简单)

    思路:用UICollectionView为父容器,用于显示个人详细信息、多行多列Tab切换。

    ①抖音个人主页包含用户信息和用户发布、喜欢的视频列表,以CollectionView为父容器即可全部实现。UICollectionView包含两个Section,第一个Section包含一个Header和一个Footer,Header 用于显示用户头像、昵称等详细信息,Footer则用于切换“作品”与“喜欢”两个tab,第二个section则用于显示短视频动图列表。

    UICollectionView指定元素固定原理

    通过重写UICollectionViewFlowLayout中的layoutAttributesForElementsInRect方法可以让UICollectionView显示诸如瀑布流、水平流动布局等各种样式的布局。其原理就是layoutAttributesForElementsInRect方法本身返回的是UICollectionView中每个元素的属性,属性中就包含元素的frame信息,通过修改frame值即可改变每个元素显示的位置,这里的元素类型分为Header、Footer、Cell,判断元素类型可将不同元素进行区分

    抖音个人主页在向上滑动时,第一个section滑动到导航栏底部时便固定位置不再上移。实现这个效果就需要将第一个section中的元素提取出来单独处理frame值。之前也介绍了,第一个section包含一个Header和一个Footer,Header用于显示用户详细信息,Footer则用于显示切换"作品"和"喜欢"的Tab栏,因此只需判断是否是第一个section的Header和Footer并修改frame值即可实现固定效果,具体代码如下:

    #import <UIKit/UIKit.h>
    
    @interface HoverViewFlowLayout : UICollectionViewFlowLayout
    
    @property (nonatomic, assign) CGFloat      topHeight;
    
    - (instancetype)initWithTopHeight:(CGFloat)height;
    
    @end
    #import "HoverViewFlowLayout.h"
    
    @implementation HoverViewFlowLayout
    
    - (instancetype)initWithTopHeight:(CGFloat)height{
        self = [super init];
        if (self){
            self.topHeight = height;
        }
        return self;
    }
    
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
        NSMutableArray<UICollectionViewLayoutAttributes *> *superArray = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
        for (UICollectionViewLayoutAttributes *attributes in [superArray mutableCopy]) {
            if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
                [superArray removeObject:attributes];
            }
        }
        
        [superArray addObject:[super layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]];
      
        for (UICollectionViewLayoutAttributes *attributes in superArray) {
            
            if(attributes.indexPath.section == 0) {
                
                if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]){
                    CGRect rect = attributes.frame;
                    if(self.collectionView.contentOffset.y + self.topHeight - rect.size.height > rect.origin.y) {
                        rect.origin.y =  self.collectionView.contentOffset.y + self.topHeight - rect.size.height;
                        attributes.frame = rect;
                    }
                    attributes.zIndex = 5;
                }
            }
            
        }
        return [superArray copy];
    }
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
        return YES;
    }
    
    @end

    ③UICollectionView指定元素下拉缩放原理

    UIScrollView的bounce属性设置为YES后,UIScrollView及其子类都会有在滑动到顶部和底部时出现弹簧拉伸效果,UICollectionView、UITableView都继承自UIScrollView,所以也有bounce属性。实现抖音个人主页的拉伸效果的代码片段如下:

    //UIScrollViewDelegate Delegate
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat offsetY = scrollView.contentOffset.y;
        if (offsetY < 0) {
            [_userInfoHeader overScrollAction:offsetY];
        }else {
            [_userInfoHeader scrollToTopAction:offsetY];
            [self updateNavigationTitle:offsetY];
        }
    }
    - (void)updateNavigationTitle:(CGFloat)offsetY {
        if (kUserInfoHeaderHeight - HK_NAVBAR_HEIGHT*2 > offsetY) {
            [self setNavBarTextColor:ColorClear];
        }
        if (kUserInfoHeaderHeight - HK_NAVBAR_HEIGHT*2 < offsetY && offsetY < kUserInfoHeaderHeight - HK_NAVBAR_HEIGHT) {
            CGFloat alphaRatio =  1.0f - (kUserInfoHeaderHeight - HK_NAVBAR_HEIGHT - offsetY)/[self navagationBarHeight];
            [self setNavBarTextColor:[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:alphaRatio]];
        }
        if (offsetY > kUserInfoHeaderHeight - [self navagationBarHeight]) {
            [self setNavBarTextColor:ColorWhite];
        }
    }
    
    ///////////////////////////////////////////////
    #pragma update position when over scroll
    
    - (void)overScrollAction:(CGFloat) offsetY {
        CGFloat scaleRatio = fabs(offsetY)/370.0f;
        CGFloat overScaleHeight = (370.0f * scaleRatio)/2;
        _topBackground.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(scaleRatio + 1.0f, scaleRatio + 1.0f), CGAffineTransformMakeTranslation(0, -overScaleHeight));
    }
    
    - (void)scrollToTopAction:(CGFloat) offsetY {
        CGFloat alphaRatio = offsetY/(370.0f - 44 - StatusBarHeight);
        _containerView.alpha = 1.0f - alphaRatio;
    }

    效果图:

                 

    代码地址:

    https://gitee.com/Steven_Hu/DouyinUserHomePage

    参考:

    https://sshiqiao.github.io/document/douyin-objectc.html#2.2

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    oo第二次总结
    oo第一次总结
    OO最后一次博客儿
    OO作业总结第三弹
    OO作业总结第二弹
    初学面向对象
    hi🎈
    散列函数及其应用
    结对项目作业
    构建之法第四,第十四章读书有感 (另补第十七章)
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/10104593.html
Copyright © 2011-2022 走看看