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

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM