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

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

作者: 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