iOS:类似于网易云音乐的刷新条目显示弹框

一、介绍

在app中使用刷新控件或者第三方刷新库是最常见的功能,在请求服务器时,获取数据的过程是处于不可见状态的,那么通过这个刷新状态可以给用户以直观的感受,这是增强用户体验的一个相当好的方法。我个人认为,有时这个方法仍有不足,就是当拉取到数据时,用户只是知道数据有了,并没有直接告知用户拉取了或者刷新了多少条数据。所以,这里我写了一个类似于网易云音乐的“朋友”模块中的一个刷新条目显示弹框。

二、思想

1、创建一个messageView,内部包含一个label,使用masonry约束,将其放到navigationBar后面,默认状态是透明的;

2、navigationBar可以是系统的,也可以是自定义的,根据需求去应用;

3、刷新结束时通过UIView的block动画改编透明度并显示,显示一定时间后自动显示隐藏;

4、创建的实例都放在基类中进行,暴露给子类去调用即可;

三、代码

ShowMessageView.h

//
//  ShowMessageView.h
//  ShowMessageTest
//
//  Created by 夏远全 on 2018/3/22.
//  Copyright ? 2018年 夏远全. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ShowMessageView : UIView

//创建显示弹框(这个直接放在基类中创建,并将该实例对象暴露给子类使用,vc的系统导航栏没有隐藏掉)
+(instancetype)createShowMessageViewInViewController:(UIViewController *)vc;

//创建显示弹框(这个直接放在基类中创建,并将该实例对象暴露给子类使用,vc的系统导航栏被隐藏掉了,传入vc自定义的导航栏customNav)
+(instancetype)createShowMessageViewInViewController:(UIViewController *)vc customNav:(UIView *)customNav;

//显示消息 (刷新结束后调用)
-(void)showMessage:(NSString *)message;

//隐藏消息 (需要在基类的viewWillDisappear调用一次就行了)
-(void)hideMessage;

@end

ShowMessageView.m

//
//  ShowMessageView.m
//  ShowMessageTest
//
//  Created by 夏远全 on 2018/3/22.
//  Copyright ? 2018年 夏远全. All rights reserved.
//

#import "ShowMessageView.h"
#import <Masonry.h>

#define isIphoneX_YML (kScreenWidth == 375.0 && kScreenHeight == 812.0) //没有横屏模式才能这么判断
#define kStatusBarHeight (isIphoneX_YML ? 44.0 : 20.0)
#define kNavigationHeight 44.0
#define kNavigationAndStatusBarHeight    (kStatusBarHeight + kNavigationHeight)

@interface ShowMessageView ()
@property (nonatomic, strong) UILabel *messageLabel;
@property (nonatomic, assign) CGFloat messsageWidth;
@end

@implementation ShowMessageView

#pragma mark - life cycle
+(instancetype)createShowMessageViewInViewController:(UIViewController *)vc
{
    ShowMessageView *messageView = [[self alloc] initWithFrame:CGRectMake(0, kNavigationAndStatusBarHeight-40, 200, 40)];

    messageView.backgroundColor = [UIColor clearColor];
    messageView.alpha = 0;
    messageView.hidden = YES;

    messageView.centerX  = vc.navigationController.navigationBar.centerX;

    [messageView setShadowForView:messageView];

    [vc.navigationController.navigationBar addSubview:messageView];

    [vc.navigationController.navigationBar sendSubviewToBack:messageView];

    [messageView setup];

    return messageView;
}

+(instancetype)createShowMessageViewInViewController:(UIViewController *)vc customNav:(UIView *)customNav;{

    ShowMessageView *messageView = [[self alloc] initWithFrame:CGRectMake(0, kNavigationAndStatusBarHeight-40, 200, 40)];

    messageView.backgroundColor = [UIColor clearColor];
    messageView.alpha = 0;
    messageView.hidden = YES;

    messageView.centerX  = customNav.centerX;

    [ShadowUtility setShadowForView:messageView];

    [customNav addSubview:messageView];

    [customNav sendSubviewToBack:messageView];

    [messageView setup];

    return messageView;
}

-(void)setup
{
    [self setDefalut];
    [self addSubViews];
    [self setupSubviewsConstraints];
}

-(void)setDefalut
{

}

#pragma mark - add subViews
-(void)addSubViews
{
    [self addSubview:self.messageLabel];
}

#pragma mark - layout subviews
-(void)setupSubviewsConstraints
{
    [self.messageLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.mas_centerX);
        make.centerY.equalTo(self.mas_centerY);
        make.height.equalTo(self.mas_height);
        if (self.messsageWidth > 0) {
            make.width.equalTo(@(MAX(100, self.messsageWidth)+20));
        }
    }];
}

#pragma mark - event response

#pragma mark - public methods
-(void)showMessage:(NSString *)message{

    self.messageLabel.text = message;

    if (message.length > 0) {
        self.messsageWidth = [message boundingRectWithSize:CGSizeMake(MAXFLOAT, 40) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil].size.width;
        [self setupSubviewsConstraints];
    }

    if (self.alpha == 0) {

        self.hidden = NO;

        [UIView animateWithDuration:0.8 animations:^{

            self.alpha = 1.0;
            self.transform = CGAffineTransformMakeTranslation(0,40+10);

        } completion:^(BOOL finished) {

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                [UIView animateWithDuration:0.3 animations:^{

                    self.alpha = 0;

                } completion:^(BOOL finished) {

                    self.hidden = YES;
                    self.transform = CGAffineTransformIdentity;
                }];

            });

        }];
    }

}

-(void)hideMessage{
    self.alpha = 0;
    self.transform = CGAffineTransformIdentity;
}

#pragma mark - private methods
- (void)setShadowForView:(UIView *)view
{
    view.layer.shadowColor = HEXCOLOR(0xaeaeae).CGColor;
    view.layer.shadowOffset = CGSizeMake(0, 0);
    view.layer.shadowRadius = 4.0;
    view.layer.shadowOpacity = 0.2;
    view.layer.shouldRasterize = YES;
    view.layer.rasterizationScale = [UIScreen mainScreen].scale;
}

#pragma mark - getters and setters
-(UILabel *)messageLabel{
    if (!_messageLabel) {
        _messageLabel = [[UILabel alloc] init];
        _messageLabel.layer.cornerRadius = 20;
        _messageLabel.layer.masksToBounds = YES;
        _messageLabel.font = [UIFont systemFontOfSize:16];
        _messageLabel.textAlignment = NSTextAlignmentCenter;
        _messageLabel.textColor = [UIColor whiteColor];
        _messageLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
    }
    return _messageLabel;
}

@end

四、使用

1、在基类创建

@property (nonatomic, strong) ShowMessageView *showMessageView; //在基类中定义实例属性
self.showMessageView = [ShowMessageView createShowMessageViewInViewController:self]; //在基类中创建实例

2、在基类实现必要的方法

- (void)viewWillDisappear:(BOOL)animated   //在基类中调用必要的方法
{
    [super viewWillDisappear:animated];
    [self.showMessageView hideMessage];
}

3、子类调用

[weakSelf.tableView.mj_header endRefreshing];
[weakSelf.showMessageView showMessage:@"刷新了20条新数据"];  //结束刷新后显示条目弹框

五、效果

 

原文地址:https://www.cnblogs.com/XYQ-208910/p/8652586.html

时间: 2024-08-09 07:33:33

iOS:类似于网易云音乐的刷新条目显示弹框的相关文章

iOS网易云音乐首页源码、动画引擎源码等

iOS精选源码 自己维护的框架, 超级多功能 图片选择SDK:支持多选,相册选择,预览,网络图预览 一款可以简单实现长按拖拽重排的 UICellCollectionView Cell框... 动画引擎 FXAnimationEngine MJCIOS/MJCSegmentInterface(分段界面框架) TYCyclePagerView iOS上的一个无限循环轮播图组件 首页广告视图 SGAdvertScrollView SliderView-自定义分段标签滚动视图,集成使用简单 轻巧便捷的t

[IOS][已越狱]配合网易云音乐,使用Bridge快速免iTunes导入音乐到“音乐”

前置:已越狱IOS设备 工具表: Bridge{bigboss源,可以使用cydown以非官方服务器下载安装} 网易云音乐{Appstore} Filza{很多源都有} 网易云试听缓存路径: /var/mobile/Containers/Data/Application/网易云音乐/Documents/UserData/Download/cache/ 遇到无法下载的音乐可以从缓存路径中提取“*.uc!”后缀有实际大小的文件,并修改后缀名称为“*.mp3”. 由于网易云试听缓存机制,缓存完成当前试

iOS 开发仿网易云音乐歌词海报

使用网易云音乐也是一个巧合,我之前一直使用QQ音乐听歌,前几天下 app 手机内存告急.于是就把QQ音乐给卸载掉了,正好晚上朋友圈里有一个朋友用网易云音乐分享了一首歌曲,于是我也就尝试下载了网易云音乐,这一下载就让我从QQ音乐粉转黑了. 从设计的角度来看,网易云音乐的界面简洁,慷慨,不像kugou音乐一打开就是各种广告.让人心烦.也不像QQ音乐那样动不动就各种音质,各种冲钻(不为用户需求考虑.仅仅想赚钱,差评).最关键的是它推荐的歌真是好听,实在是太懂我了,真的是非常用心的在做音乐. 废话不多说

Python 获取网易云音乐热门评论

--> html { line-height: 1.6 } body { font-family: -apple-system-font, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; background-color: #f3f3f3; line-height: inherit } body.ric

网易云音乐

模拟制作网易云音乐(AudioContext) 记得好早前在慕课网上看到一款可视化音乐播放器,当前是觉得很是神奇,还能这么玩.由于当时刚刚转行不久,好多东西看得稀里糊涂不明白,于是趁着现在有时间又重新梳理了一遍,然后参照官网的API模拟做了一款网易播放器.没有什么创新的点,只是想到了就想做一下而已. 效果可以看这里:http://music.poemghost.com/,如果看不了,说明博主的服务器已经不在工作啦.(建议使用电脑浏览器打开,同时切换到手机模式来打开,因为在手机上测试时有问题,而且

实现 60fps 的网易云音乐首页

网易云音乐是一款很优秀的音乐软件,我也是它的忠实用户.最近在研究如何更好的开发TableView,接着我写了一个Model驱动的小框架 - MDTable.为了去验证框架的可用性,我选择了网易云音乐的首页来作为Demo,语言是Swift 3. 本文的内容包括: 实现网易云音乐首页的思路如何建立一个轻量级的UITableViewController(不到100行)性能瓶颈原因以分析及如何优化到接近60fps Note:本文并没有用Reveal去分析网易云音乐iOS客户端的原始UI布局,所以实现方式

《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目

CloudReader 一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目.项目采取的是Retrofit + RxJava + MVVM-DataBinding架构开发.开发中所遇到的各种问题已归纳在这里. github地址:CloudReader What can be learned about this project 那么,从本项目中你能学到哪些知识呢? 1.干货集中营内容与豆瓣电影书籍内容. 2.高仿网易云音乐歌单

Android 开发之网易云音乐(或QQ音乐)的播放界面转盘和自定义SeekBar的实现

这个东西我在eoeAndroid上首发的,但没有详细的实现说明:http://www.eoeandroid.com/thread-317901-1-1.html 在csdn上进行详细的说明吧.(同时上两个社区,这真是个坏毛病,以后专注csdn好了). 1.用过网易云音乐客户端应该都懂得它那个播放界面,是蛮炫的.先看我实现的效果图吧: 自定义SeekBar这里少了点东西,进度条应该有两种颜色表示进度,一种是当前播放进度,一种是下载进度.我只实现了第一个,第二个要实现的话还需要重载SeekBar.

批量删除网易云音乐【我喜欢的音乐】列表中的歌曲

?网易云音乐貌似没有提供批量操作的功能,而这个歌单好像又不能删掉,所以删的时候得一个个删,相当蛋疼.不过看了下删除操作,是请求一个api,传递相应参数即可. 首先打开歌单页面,地址是: http://music.163.com/#/my/m/music/playlist?id=xxxxx 其中xxxxx是歌单的ID号,打开console,随便删一首歌,可以看到网络请求为: /api/playlist/manipulate/tracks?csrf_token=64f353b064b83d3c692