阅读 TCMessageBox toast 源码小记

TCMessageBox toast 是一个很小的 toast 展示,主要效果有以下2种:

            

看了一下实现方式,也是挺简单的,不外乎就是创建一个view,中间再放一个 activityIndicator 和一个 label,最后再把整个view展示在 mianView 的中间而已。

看代码:

#import <Foundation/Foundation.h>

@interface TCMessageBox : NSObject

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch withActivityIndicator:(BOOL)withIndicator offset:(CGSize)offset;

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch withActivityIndicator:(BOOL)withIndicator;

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch;

+(BOOL)presenting;
+(void)hide;
+(void)hideIn:(NSTimeInterval)delay;
@end
#import "TCMessageBox.h"
#import <QuartzCore/QuartzCore.h>

#define PADDING 10
#define DURATION 0.25

TCMessageBox *_theMsgBox;

@implementation TCMessageBox{
    UILabel *_label;
    UIView *_darkBox;
    UIActivityIndicatorView *_indicator;
    UIControl *_control;
    UIView * _backgroundView;
}

-(id)init{
    self = [super init];
    if (self) {

        _indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

        _label = [[UILabel alloc] init];
        _label.backgroundColor = [UIColor clearColor];
        _label.textColor = [UIColor whiteColor];
        _label.font = [UIFont fontWithName:@"Marion-Bold" size:15];
        _label.textAlignment = NSTextAlignmentCenter;
        _label.numberOfLines = 3;

        _darkBox = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 160, 120)];
        _darkBox.layer.backgroundColor = [UIColor colorWithWhite:0.05 alpha:0.50].CGColor;
        _darkBox.layer.cornerRadius = 10;
        _darkBox.layer.shadowColor = [UIColor colorWithWhite:0.6 alpha:0.8].CGColor;
        _darkBox.layer.shadowOffset = CGSizeMake(4, 4);
        _darkBox.layer.shadowOpacity = 1.0;

        _control = [[UIControl alloc] init];
        [_control addTarget:[TCMessageBox class] action:@selector(hide) forControlEvents:UIControlEventTouchUpInside];

        [_control addSubview:_darkBox];
        [_darkBox addSubview:_indicator];
        [_darkBox addSubview:_label];
    }
    return self;
}

-(void)layoutSubviewsWithActivityIndicator:(BOOL)withIndicator hideByTouch:(BOOL)hideByTouch offset:(CGSize)offset{
    CGRect rect, r2;
    UIWindow *window;

    if (withIndicator) {
        //cal indicator's frame
        rect = _indicator.frame;
        rect = CGRectMake((_darkBox.frame.size.width - rect.size.width) / 2, (_darkBox.frame.size.height - rect.size.height) / 2, rect.size.width, rect.size.height);
        _indicator.frame = rect;

        //cal label's frame
        rect = CGRectMake(PADDING, rect.origin.y + rect.size.height + PADDING, _darkBox.frame.size.width - PADDING * 2, 0);
        rect.size.height = _darkBox.frame.size.height - rect.origin.y - PADDING;
        _label.frame = rect;

        [_indicator startAnimating];
    }else{
        _indicator = nil;

        //cal label's frame
        rect = _darkBox.frame;
        rect = CGRectMake(PADDING, PADDING, rect.size.width - PADDING * 2, rect.size.height - PADDING * 2);
        _label.frame = rect;
    }

    window = [[UIApplication sharedApplication].windows objectAtIndex:0];

    r2 = window.rootViewController.view.bounds;

    //cal _darkBox's frame , move the _darkBox to the center(or + offset) of the mainscreen
    rect = _darkBox.frame;
    rect.origin.x = (r2.size.width - rect.size.width) / 2 + offset.width;
    rect.origin.y = (r2.size.height - rect.size.height) / 2 + offset.height;
    _darkBox.frame = rect;

    CGRect fullScreenRect = [window frame];
    _backgroundView = [[UIView alloc] initWithFrame:fullScreenRect];
    if (hideByTouch) {
        _control.frame = r2;
        [_control addSubview:_darkBox];
        [_backgroundView addSubview:_control];
    }else{
        _control = nil;
        [_backgroundView addSubview:_darkBox];
    }
    [window.rootViewController.view addSubview:_backgroundView];
}

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch withActivityIndicator:(BOOL)withIndicator offset:(CGSize)offset{
    [_theMsgBox hide:NO];
    _theMsgBox = [[TCMessageBox alloc] init];
    [_theMsgBox layoutSubviewsWithActivityIndicator:withIndicator hideByTouch:hideByTouch offset:offset];
    _theMsgBox->_label.text = message;

    _theMsgBox->_darkBox.alpha = 0.0;
    [UIView animateWithDuration:DURATION animations:^{
        _theMsgBox->_darkBox.alpha = 1.0;
    } completion:nil];
}

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch withActivityIndicator:(BOOL)withIndicator{
    [TCMessageBox showMessage:message hideByTouch:hideByTouch withActivityIndicator:withIndicator offset:CGSizeZero];
}

+(void)showMessage:(NSString *)message hideByTouch:(BOOL)hideByTouch{
    [TCMessageBox showMessage:message hideByTouch:hideByTouch withActivityIndicator:NO offset:CGSizeZero];
}

+(void)hide{
    [_theMsgBox hide:YES];
}

-(void)hide:(BOOL)animate{
    if (animate) {
        [UIView animateWithDuration:DURATION animations:^{
            _darkBox.alpha = 0;
        } completion:^(BOOL finished) {
            [self hide:NO];
        }];
    }else{
        [_backgroundView removeFromSuperview];
        [_control removeFromSuperview];
        [_darkBox removeFromSuperview];
    }
}

-(void)hideIn:(NSNumber *)delay{
    sleep(delay.doubleValue);
    [self performSelectorOnMainThread:@selector(hide:) withObject:@YES waitUntilDone:YES];
}

+(void)hideIn:(NSTimeInterval)delay{
    [_theMsgBox performSelectorInBackground:@selector(hideIn:) withObject:@(delay)];
}

+(BOOL)presenting{
    return (_theMsgBox->_control && _theMsgBox->_control.superview) || (!_theMsgBox->_control && _theMsgBox->_darkBox.superview);
}
@end

这样一封装好,接口使用起来还是挺方便的。当然,代码还有许多可以改进的地方,比如把 hideIn:接口功能添加到showMessage:hideByTouch:中这样就可以只调用一个接口就行了,不用这样

[TCMessageBox
showMessage:@"test message"
hideByTouch:NO];

[TCMessageBox hideIn:2.0f];

调用2个接口了,能简则简嘛~

时间: 2024-11-09 00:50:45

阅读 TCMessageBox toast 源码小记的相关文章

Android Toast源码分析

前言 这周去杭州参加了百阿培训,见到了传说中的牛人多隆大神.从多隆大神身上看到了做技术人的纯粹,单纯.除了见到多隆大神,这次培训并没有太多的收获,反而培训过程中遇到了好多产品上的Bug,远程办公快累到死.总结一下跟Toast相关的问题,首先从深入学习Toast的源码实现开始. Toast源码实现 Toast入口 我们在应用中使用Toast提示的时候,一般都是一行简单的代码调用,如下所示: Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(

[Android阅读代码]android-async-http源码学习一

android-async-http 下载地址 一个比较常用的Http请求库,基于org.apache.http对http操作进行封装. 特点: 1.每一个HTTP请求发生在UI线程之外,Client通过回调处理HTTP请求的结果,使得Client代码逻辑清晰 2.每一个请求使用线程池管理执行 3.支持gzip , cookie等功能 4.支持自动重试连接功能 [Android阅读代码]android-async-http源码学习一,布布扣,bubuko.com

daily news新闻阅读客户端应用源码(兼容iPhone和iPad)

daily news新闻阅读客户端应用源码(兼容iPhone和iPad),也是一款兼容性较好的应用,可以支iphone和ipad的阅读阅读器源码,设计风格和排列效果很不错,现在做新闻资讯客户端的朋友可以参考一下吧. 源码下载: http://code.662p.com/view/6384.html 详细说明:http://ios.662p.com/thread-1526-1-1.html

如何阅读Android系统源码-收藏必备

对于任何一个对Android开发感兴趣的人而言,对于android系统的学习必不可少.而学习系统最佳的方法就如linus所言:"RTFSC"(Read The Fucking Source Code).下面从知乎整理了一些优质回答,以飨读者. 巨人的肩膀 AOSP项目官方: https://source.android.com/source/index.html这个一定要先读. 项目介绍, 代码下载, 环境搭建, 刷机方法, Eclipse配置都在这里. 这是一切的基础. Androi

android五子棋游戏、资讯阅读、大学课程表、地图拖拽检测、小说搜索阅读app等源码

Android精选源码 Android 自动生成添加控件 android旋转动画.圆形进度条组合效果源码 一款很强的手机五子棋app源码 android地图拖拽区域检测效果源码 实现Android大学课表效果APP源码 android完全免费的小说搜索阅读app 一个互联网资讯阅读平台和良好的阅读体验的App Android优质博客 Android中高效的显示图片Bitmap的内存模型 相对于文字来说,图片的表达更直接.更有冲击力.更容易吸引用户的眼球.设计师们也理所当然的喜欢用图片来传达信息.

利其器:如何使用source insight阅读android部分源码

? ? 为了便于学习这个安卓驱动,需要阅读源码加深印象,但是安卓源码太大了,所以我们只拷贝三个目录到windows下面用source insight查看.怎么知道拷贝哪三个目录呢?好吧,是老师告诉的:frameworks.hardware.system.至于为什么是这三个目录,可以查书看看源码各个目录的作用就好了. 注意:不要贪多,源码用到哪些就拷贝哪些,如果你的电脑性能好,可以考虑索引全部源码,但是没必要,学习不就是抓关键点么. ? ? 好了,首先到虚拟机(任意开发环境均可)下面,把这三个目录

源码阅读系列:源码阅读方法

一.前提条件 1.纯熟扎实的语言基础 ??如果你学java,却对反射.泛型.注解一直半解,还是不要去读什么框架了,回去把java基础打扎实反而对你自身更有益. 2.UML能力 ??在软件工程中,UML在软件的不同生命周期阶段扮演着非常重要的角色,没有好的UML水平,面对大型的项目源码会束手无策. 3.对业务的理解 ??如果你要阅读的项目业务性比较强,事先对业务有一定的了解是必须的. 4.设计模式.重构的掌握 ??编程语言什么的没什么好说.着重提一个:设计模式由于Android源代码用到各种各样的

如何阅读android framework源码

但如果想深入的了解Android系统, 那么可以看下我的一些简单的总结. 知识 Java Java是AOSP的主要语言之一. 没得说, 必需熟练掌握. 熟练的Android App开发 Linux Android基于Linux的, 并且AOSP的推荐编译环境是Ubuntu 12.04. 所以熟练的使用并了解Linux这个系统是必不可少的. 如果你想了解偏底层的代码, 那么必需了解基本的Linux环境下的程序开发. 如果再深入到驱动层, 那么Kernel相关的知识也要具备. Make AOSP使用

Android拓展系列(10)--使用Android Studio阅读整个Android源码

之前一直在windows下用source insight阅读android源码,效果非常好.后来远程异地服务器,网络限制,一直用ssh + vim,现在主要还是以这种方式.最近发现一个不错的东西(早就有了),在android源码中有这么一个目录development/tools/idegen.顾名思义,是生成ide的project文件,主要是生成intellij的project文件,当然夜可用于android studio.使用之后,发现效果超棒,所以这里专门撰文推荐. 1.效果图 2.编译id