美文网首页
仿网易云音乐账号界面交互效果

仿网易云音乐账号界面交互效果

作者: DevHuangjb | 来源:发表于2020-03-04 21:09 被阅读0次

之前项目中产品经理丢给我一个页面,要求交互效果要和网易云音乐App中"账号"模块一样。

网易云效果.2020-03-04 16_57_17.gif

拿到需求后,我关注到松手动作有一个bounce的效果,所以我谨慎的猜测外层是一个UITableView,而头部视图可能是UITableView的tabelHeaderView。

接下来我使用界面分析神器Reveal对网易云音乐的界面进行分析:

reveal截图.jpg

可见最外层确实是一个tableview。

跟我猜测有出入的是头部视图是作为NMSettingTable的subView添加进去的,而不是tableHeaderView:

_subviewCache:@[#"<NMSettingCardContainerView: 0x12e22be30; frame = (0 -284; 375 284); clipsToBounds = YES; layer = <CALayer: 0x12e22bfd0>>"

�注意NMSettingCardContainerView的实例clipsToBounds = YES;

到这里已经基本有眉目了,NMSettingHeadView和NMVipCardView作为NMSettingCardContainerView的subView。NMSettingCardContainerView作为NMSettingTableView的subView。NMSettingCardContainerView的height随着NMSettingTableView的contentOffset而变化,高度一变化,NMVipCardView遮挡的部分自然就会显现出来。而NMSettingHeadView和NMVipCardView的frame属性NMSettingTableView的contentOffset做一下微调就可以。

主要代码,代码已经去掉业务相关的部分

#import "ProfileViewController.h"
#import "ProfileHeadView.h"
#import "ProfileRedCardView.h"

#define ContainerViewH  200
#define HeadViewH  150
#define DragDistance 120

@interface SettingTableView : UITableView

@end

@implementation SettingTableView

- (void)setContentOffset:(CGPoint)contentOffset {
    CGFloat y = contentOffset.y < - ContainerViewH - DragDistance ? - ContainerViewH - DragDistance : contentOffset.y;
    [super setContentOffset:CGPointMake(0, y)];
}

@end


@interface ProfileViewController ()<UITableViewDelegate, UITableViewDataSource, ProfileHeadViewDelegate, ProfileToolCellDelegate>

@property (nonatomic, strong) SettingTableView *tableView;

@property (nonatomic, strong) UIView *containerView;

@property (nonatomic, strong) ProfileHeadView *headView;

@property (nonatomic, strong) ProfileRedCardView *redCardView;

@end


@implementation ProfileViewController
@dynamic viewModel;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.fd_prefersNavigationBarHidden = YES;
    
    [self.view addSubview:self.tableView];
    [self.view addSubview:self.customNavBar];
    [self.customNavBar addSubview:self.setBtn];
    [self.tableView addSubview:self.headerView];
    [self.headerView addSubview:self.headView];
    [self.headerView addSubview:self.redCardView];
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    CGFloat offsetY = scrollView.contentOffset.y;
    //    NSLog(@"%f",offsetY);
    if (offsetY < -ContainerViewH) {
        CGFloat dis = -(offsetY + ContainerViewH);
        dis = dis > DragDistance ? DragDistance : dis;
        self.containerView.top = - ContainerViewH - dis;
        self.containerView.height = ContainerViewH + dis;
        //微调headView和CardView的frame
        self.redCardView.top = HeadViewH + dis * .5;
        self.headView.top = dis *.25;
    }else {
        self.containerView.top = -ContainerViewH;
        self.containerView.height = ContainerViewH;
        self.headView.top = 0;
        self.redCardView.top = HeadViewH;
    }
}

#pragma mark - getter
- (SettingTableView *)tableView {
    if (_tableView == nil) {
        _tableView = [[SettingTableView alloc]initWithFrame:CGRectMake(0, kTopHeight, kScreenW, kScreenH - kTopHeight) style:UITableViewStyleGrouped];
        _tableView.bounces = YES;
        _tableView.backgroundColor = WhiteColor;
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.sectionFooterHeight = 0.0;
        _tableView.sectionHeaderHeight = 10.0;
        _tableView.showsVerticalScrollIndicator = NO;
        _tableView.showsHorizontalScrollIndicator = NO;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tableView.contentInset = UIEdgeInsetsMake(ContainerViewH, 0, kTabBarHeight, 0);
        _tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
        _tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
    }
    return _tableView;
}

- (UIView *)containerView {
    if (_containerView == nil) {
        _containerView = [UIView new];
        _containerView.frame = CGRectMake(0, -ContainerViewH, kScreenW, ContainerViewH);
        _containerView.clipsToBounds = YES;
    }
    return _containerView;
}

- (ProfileHeadView *)headView {
    if (_headView == nil) {
        _headView = [[ProfileHeadView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, HeadViewH)];
        _headView.delegate = self;
    }
    return _headView;
}

- (ProfileRedCardView *)redCardView {
    if (_redCardView == nil) {
        _redCardView = [[ProfileRedCardView alloc] initWithFrame:CGRectMake(0, HeadViewH, kScreenW, 110)];
    }
    return _redCardView;
}

@end

最终的效果如下:

项目效果.gif

相关文章

网友评论

      本文标题:仿网易云音乐账号界面交互效果

      本文链接:https://www.haomeiwen.com/subject/rrgilhtx.html