项目中的工具类

2019-5-17 王建伟 iOS开发

项目中我们一般需要新建一个工具类,用来实现一些项目中经常使用的功能,方便复用,这边我收集了一些自己经常使用的功能

1.添加文字提示框

+(void)showHubTipWithString:(NSString *)string offsetY:(CGFloat)y{  
    if (string && string.length > 0) {
        dispatch_async(dispatch_get_main_queue(), ^{
            MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[[UIApplication sharedApplication] keyWindow] animated:YES];
            hud.mode = MBProgressHUDModeText;
            hud.detailsLabel.font = [UIFont boldSystemFontOfSize:17.0];
            hud.detailsLabel.text =string;
            hud.margin = 20.f;
            hud.offset=SPPoint(0, y);
            hud.removeFromSuperViewOnHide = YES;
            [hud hideAnimated:YES afterDelay:0.8];
        });
    }    
}

2.添加加载提示框

+(MBProgressHUD*)showLoadingHubAddedTo:(UIView*)view{
    MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:view];
    hud.contentColor=[UIColor whiteColor];
    hud.bezelView.backgroundColor=[UIColor colorWithWhite:0.1 alpha:1];
    hud.mode = MBProgressHUDModeIndeterminate;
    hud.detailsLabel.font=SPFont(17);
    hud.minShowTime=2;
    hud.userInteractionEnabled = YES;
    hud.removeFromSuperViewOnHide = YES;
    [view addSubview:hud];
    return hud;
}

3.手机号验证

+(BOOL)validateMobile:(NSString*)mobile{
    NSString*mobileRegex=@"^(1[123456789][0-9]{9}$)";
    NSPredicate*mobileTest=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileRegex];
    return [mobileTest evaluateWithObject:mobile];
    
}

4.密码验证

+(BOOL)validatePassword:(NSString*)password{
    NSString*passwordRegex=@"^([a-zA-Z0-9]{6,12}$)";
    NSPredicate*passwordTest=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",passwordRegex];
    return [passwordTest evaluateWithObject:password];  
}

5.获取段落行高

+(CGFloat)GetCellHeightWithString:(NSString *)string width:(CGFloat)width attributes:(NSDictionary *)attributes{
    
    
    
    CGRect sizestring = [string boundingRectWithSize:CGSizeMake(width,MAXFLOAT) options:
                        NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading  attributes:attributes context:nil];
    
    return ceil(sizestring.size.height);
}

6.秒数到时间到转化

+(NSString*)changeNumberToTime:(NSInteger)number{
    NSString*minute=[NSString stringWithFormat:@"%02ld",number%3600/60];
    NSString*second=[NSString stringWithFormat:@"%02ld",number%60];
    return [NSString stringWithFormat:@"%@:%@",minute,second];
    
}

评论(0) 浏览(5)

简单的网络加载图的实现

2019-5-10 王建伟 iOS开发

在编写项目的时候我们需要进行网络的加载,那么网络加载需要时间和重新加载的选项,所以我们可以需要一个加载界面,在网络加载的过程中,重新加载的时候呈现

编辑一个简单的网络加载界面,我们需要一个加载动画,以及加载成功或者失败的处理方法

1.建立一个UIView的子类,LoadingView

2.我们需要的属性:
a:CAShapeLayer*_loadingShapeLayer(制作简单动画);
b:UILabel*promptLabel(提示文字);
c:UIButton*reloadButton(重新加载按键) ;
d:LoadingFailBlock failBlock(加载失败的事件处理块)

3.初始化界面

+(LoadingView*)ShowLoadingViewFrame:(CGRect)frame withSuperView:(UIView *)view{
     LoadingView*loadingview=[[LoadingView alloc]initWithFrame:frame];
     [view addSubview:loadingview];
     [loadingview loadingShapeLayerAnimation];
     return loadingview;
}

-(instancetype)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
        self.backgroundColor=[UIColor whiteColor];
        _loadingShapeLayer=[[CAShapeLayer alloc]init];
        _loadingShapeLayer.frame=SPFrame(frame.size.width/2-40, frame.size.height/2-100, 80,80 );
        _loadingShapeLayer.path=[UIBezierPath bezierPathWithOvalInRect:SPFrame(0, 0, 80,80 )].CGPath;
        _loadingShapeLayer.fillColor=nil;
        _loadingShapeLayer.strokeColor=[UIColor lightGrayColor].CGColor;
        _loadingShapeLayer.lineWidth=2;
        _loadingShapeLayer.lineJoin=kCALineCapRound;
        _loadingShapeLayer.lineDashPattern=@[@15,@8];
        [self.layer addSublayer:_loadingShapeLayer];
        
        promptLabel=[[UILabel alloc]initWithFrame:SPFrame(frame.size.width/2-40, frame.size.height/2-100, 80,80 )];
        promptLabel.backgroundColor=[UIColor clearColor];
        promptLabel.text=@"正在加载";
        promptLabel.textColor=[UIColor lightGrayColor];
        promptLabel.font=SPFont(15);
        promptLabel.textAlignment=NSTextAlignmentCenter;
        [self addSubview:promptLabel];
      
    }
    
    return self;
}

4.实现方法:加载成功

-(void)LoadingSuccessComplation:(void (^)(void))complation{
    SPSelf;
    [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0.0f options:UIViewAnimationOptionLayoutSubviews animations:^{
        weakSelf.transform=CGAffineTransformMakeScale(0.001, 0.001);
    } completion:^(BOOL finished) {
        [weakSelf removeFromSuperview];
        
    }];
    
    if(complation){
       complation();
    }

    
}

5.实现方法:加载失败

- (void)LoadingFailComplation:(void (^)(void))complation{
    [self stopLoadingShapeLayerAnimation];
    promptLabel.text=@"加载失败";
    [self createReloadingButton];
    SPSelf;
    if(complation){
        weakSelf.failBlock = complation;
    }
    
}
-(void)createReloadingButton{
    reloadButton=[[UIButton alloc]initWithFrame:SPFrame(0, 0, 100, 30)];
    reloadButton.center=SPPoint(self.frame.size.width/2, self.frame.size.height/2+50);
    [reloadButton setTitle:@"重新加载" forState:UIControlStateNormal];
    [reloadButton setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
    reloadButton.backgroundColor=[UIColor whiteColor];
    reloadButton.layer.cornerRadius=14;
    reloadButton.layer.masksToBounds=YES;
    reloadButton.layer.borderWidth=1;
    reloadButton.layer.borderColor=[UIColor orangeColor].CGColor;
    reloadButton.titleLabel.font=SPFont(14);
    [reloadButton addTarget:self action:@selector(reloadEvent) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:reloadButton];
    
}
/*
 *重新加载按键点击事件*
 */
-(void)reloadEvent{
    [reloadButton removeFromSuperview];
    [self loadingShapeLayerAnimation];
    self.failBlock();
    
}

6.动画实现

/*
 *load圈转动*
 */
-(void)loadingShapeLayerAnimation{
    CABasicAnimation*rotate=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotate.fromValue=0;
    rotate.toValue=@(M_PI*2);
    rotate.duration=3;
    rotate.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    rotate.repeatCount=HUGE;
    rotate.fillMode=kCAFillModeForwards;
    rotate.removedOnCompletion=NO;
    [_loadingShapeLayer addAnimation:rotate forKey:rotate.keyPath];
    
}

评论(0) 浏览(12)

轮播图的封装

2019-4-26 王建伟 iOS开发

新产品项目中需要编写一个轮播图的功能,效果如下图所示:

其中我们需要用到一个第三方库:iCarousel,这是一个做轮播图非常强大的库,基本可以满足日常开发的需求,我们将在此库的基础上编写实现我们需要的轮播图

首先建立一个基础与UIView的子类:NSRoastView

需要2个属性,1.NSTimer用来实现图片的自动轮播;2.iCarousel第三方库

初始化

实现iCarousel代理方法

实现方法让他能自动轮播

评论(0) 浏览(13)

推荐一个原型制作工具墨刀

2019-4-19 王建伟 iOS开发

最近一周都是在商量新产品的功能和制作简易的产品原型,这边我用的墨刀来进行原型的制作

在墨刀,你既可以创建移动端项目(iPhone/Android)、平板项目、也可以创建Web/电视项目、Watch项目,并可以自定义尺寸,为各种屏幕创建原型。

登陆墨刀之后,点击“新建项目”即可。

当然,也可以选择“从模板中创建项目”。

鼠标悬浮在模板上方,点击“使用模板”,就能创建该模板项目。

创建好项目后,进入到工作区

1.添加页面

添加同级页面:选中一个页面,再点击页面列表顶部的「添加新页面」,便可以新建该页面的同级页面。

添加子级页面:鼠标悬浮某页面上,点击「...」展开更多按钮,单击「添加子页面」即可为该页面添加子级页面。目前最多支持创建7级页面。

2.修改页面名称

双击修改页面名称:可使用“数字”+“页面功能”方式命名,既便于页面识别,又可弥补多级列表演示时的不足,更清晰地展示页面逻辑关系。<> /p

3.调整页面顺序

拖拽调整页面顺序:拖动某页面在页面列表上下移动位置即可。如果将页面 A 移动为页面 B 的次级页面,直接拖拽 A 至 B 区域处即可。

4.复制/转移/删除页面

鼠标悬浮某页面,页面名称右侧会显示「...」更多按钮,点击更多按钮展开「创建副本」、「移动到」以及「删除」的按钮。

5.编辑页面式样

在右侧的“页面设置面板”,你可以选择页面是“竖屏”还是“横屏”演示,可以修改背景颜色。

可以选择是否显示“布局”,并可以修改“列数”/"间隔"/“尺寸”。

可以选择是否显示“网格”,并可以调节网格大小。

可以查看当前页面链接数,并在这里一键删除。

6.添加组件和图标

在最右的设置面板左侧里有“组件”、“我的组件”、“图标”库,点击即可打开相应的素材库。

组件(官方组件)库:墨刀官方提供丰富的组件库,除了基础组件,还有苹果的 iOS, 谷歌的Material design, 微信的 WeUI,蚂蚁金服的 Ant Design, Windows 10 等多套组件库。这些都可以直接使用,画原型效率大大提升。

我的组件:你自定义的组件库。

图标:覆盖各领域的图标,来自 Font Awesome, Material Design 和墨刀图标系列。

墨刀目前有两种方式添加组件/图标到画布上:

1 双击组件/图标

2 拖拽组件/图标到画布

对于左侧(在“推荐”模式下)的“快捷组件”来说,还有第三种添加方式:按住对应的快捷键然后鼠标画出。比如画“长方形”组件,就按住“R”。至于其他组件用什么快捷键,鼠标悬浮在“快捷组件”上就可以看到啦!

7.编辑组件属性

选中组件,右侧便会呈现出组件的设置面板。

在面板里可以编辑组件的各种属性,比如位置、大小、颜色、透明度、阴影、动效等等。

选中多个组件,可以编辑它们的布局方式,比如“左对齐”、“右对齐”、“居中对齐“、“水平等间距”、“垂直等间距”…

利用好这些功能就能简单的绘制一个原型满足日常需求了

标签: 原型制作工具简单的功能介绍

评论(0) 浏览(37)

runtime的一些其他常见用法

2019-4-12 王建伟 iOS开发

上篇我们利用runtime来实现了按键点击范围的扩大,其实runtime还有许多常见用法,比如:动态获取类名,动态获取类的成员变量,动态获取类的属性列表,动态获取类的方法列表,动态获取类所遵循的协议列表,动态添加新的方法,类的实例方法实现的交换,动态属性关联,消息发送与消息转发机制等。下面就介绍一些常见的用法

1.获取类名

动态的获取类名是比较简单的,使用class_getName(Class)就可以在运行时来获取类的名称。class_getName()函数返回的是一个char类型的指针,也就是C语言的字符串类型,所以我们要将其转换成NSString类型,然后再返回出去。下方的+fetchClassName:方法就是我们封装的获取类名的方法

2.获取成员变量

下方这个+fetchIvarList:这个方法就是我们封装的获取类的成员变量的方法。当然我们在获取成员变量时,可以用ivar_getTypeEncoding()来获取相应成员变量的类型。使用ivar_getName()来获取相应成员变量的名称。下方就是对获取成员变量的功能的封装。返回的是一个数组,数组的元素是一个字典,而字典中存储的就是相应成员变量的名称和类型。

3.获取成员属性

上面获取的是类的成员变量,那么下方这个+fetchPropertyList:获取的就是成员属性。当然此刻获取的只包括成员属性,也就是那些有setter或者getter方法的成员变量。下方主要是使用了class_copyPropertyList(Class,&count)来获取的属性列表,然后通过for循环通过property_getName()来获取每个属性的名字。当然使用property_getName()获取到的名字依然是C语言的char类型的指针,所以我们还需要将其转换成NSString类型,然后放到数组中一并返回。

4.获取类的实例方法

接下来我们就来封装一下获取类的实例方法列表的功能,下方这个+fetchMethodList:就是我们封装的获取类的实例方法列表的函数。在下方函数中,通过class_copyMethodList()方法获取类的实例方法列表,然后通过for循环使用method_getName()来获取每个方法的名称,然后将方法的名称转换成NSString类型,存储到数组中一并返回。

5.动态添加方法实现

下方就是动态的往相应类上添加方法以及实现。下方的+addMethod方法有三个参数,第一个参数是要添加方法的类,第二个参数是方法的SEL,第三个参数则是提供方法实现的SEL。稍后在消息发送和消息转发时会用到下方的方法。下方主要是使用class_getInstanceMethod()和method_getImplementation()这两个方法相结合获取相应SEL的方法实现。下方的IMP其实就是Implementation的方法缩写,获取到相应的方法实现后,然后再调用class_addMethod()方法将IMP与SEL进行绑定即可。

6.方法实现交换

下方就是讲类的两个方法的实现进行交换。如果将MethodA与MethodB的方法实现进行交换的话,调用MethodA时就会执行MethodB的内容,反之亦然。

评论(0) 浏览(16)

利用runtime实现按键点击范围放大

2019-4-4 王建伟 iOS开发

在编写项目的过程中我们一般都会遇到这样的情况,按键设计的比较小,用户不方便点击,造成体验很差这种状况,我们就需要在不改变按键UI的情况下实现按键点击范围放大

这时候我们就需要用的runtime机制,在程序运行和编译的时候做一个小动作,改变一下按键的点击范围

首先我们先建立一个button的分类来扩充一下按键的方法

设定一些静态的常量

static char topNameKey

static char rightNameKey

static char bottomNameKey

static char leftNameKey

然后编写扩大范围的方法

返回一个扩大的范围

改写按键点击事件,让点击范围变大

评论(0) 浏览(19)

数据存储方式FMDB

2019-3-29 王建伟 iOS开发

FMDB说iOS平台的SQLite数据库框架,使用起来更加面向对象,省去了很多麻烦,冗余的C语言代码,对比苹果自带的Core Data框架,更加轻量级和灵活,提供了多线程安全的数据库操作方法,有效的防止数据混乱

FMDB有三个主要的类

FMDatabase:一个FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句

FMResultSet:使用FMDatabase执行查询后的结果集

FMDatabaseQueue:用于在多线程执行多个查询或更新,它是线程安全的

打开数据库,通过指定SQLite数据库文件路径来创建FMDatabase对象

FMDatabase*db=[FMDatabase databaseWithPath:path];

if(![db open]){NSLog(@"数据库打开失败");}

文件路径有三种情况

(1) 具体文件路径,如果不存在会自动创建

(2) 空字符串@“”,会在临时目录创建一个空的数据库,当FMDatabase连接关闭时,数据库文件也被删除

(3) nil会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁

在FMDB中,除查询以外的所有操作,都被称为“更新” create drop insert update delete等

使用executeUpdate:方法执行更新

-(BOOL)executeUpdate:(NSString*)sql

-(BOOL)executeUpdateWithFormat:(NSString*)format,...

-(BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray*)arguments

查询方法

-(FMResultSet*)executeQuery:(NSString*)sql,...

-(FMResultSet*)executeQueryWithFormat:(NSString*)format,...

-(FMResultSet*)executeQuery:(NSString*)sql withArgumentInArray:(NSArray*)arguments

遍历结果集

while([rs next]){NSString*name = [rs stringForColumn:@"name"];int age=[rs intForColumn:@"age"];double score = [rs doubleForColumn:@"score"];}

示例代码

评论(0) 浏览(18)

数据存储方式NSUserDefaults

2019-3-22 王建伟 iOS开发

很多iOS应用都支持偏好设置,比如保存用户账号,密码等,iOS提供了一套标准等解决方案来为应用加入偏好设置功能,每个应用都有个NSUserDefaults实例,通过它来存取偏好设置

保存数据

读取数据

补充说明

偏好设置是专门用来保存应用程序等配置信息的,一般情况不要在偏好设置中保存其他数据。如果利用偏好设置来存储数据,默认就是存储在Preferences文件夹下面的,偏好设置会将所有的数据都存储到同一个文件中

使用偏好设置对数据进行保存之后,它保存到系统的时间是不确定的,会在将来某个时间点自动将数据保存到Preferences文件夹下面,如果需要即刻将数据存储,可以使用[defaults synchronize]

所有的信息都写在一个文件中,对比简单的plist可以保存和读取基本的数据类型

评论(0) 浏览(26)

iOS网络数据安全

2019-3-15 王建伟 iOS开发

在开发应用的时候,数据的安全性很重要,一般会使用post请求来加强数据的安全性,但是这样并不能解决问题,很多软件都可以拦截查看手机的请求数据,所以在提交用户隐私数据时,一般不要使用明文提交,需要进行加密处理

这篇我们讲简单介绍一下最常用的加密算法,MD5

MD5:全称Message Digest Algorithm 5,翻译为“消息摘要算法第5版”

对输入信息生成唯一的128位散列值

输入两个不同的明文不会得到相同的输出值,根据输出值,不能得到原始的明文,即其过程不可逆

由于MD5加密算法具有较好的安全性,而且免费,因此该加密算法被广泛使用,主要运用在数字签名,文件完整性验证以及口令加密等方面

但是现在的MD5已不再是绝对的安全,对此,可以对MD5稍作改进,以增加解密的难度

加盐:在明文的固定位置插入随机串,然后再进行MD5

先加密,后乱序,先对明文进行MD5,然后对加密得到的MD5串的字符进行乱序

评论(0) 浏览(29)

iOS开发中对于网络缓存的处理

2019-3-8 王建伟 iOS开发

iOS开发中网络缓存苹果已经提供了比较好用的NSURLCache类,但是只支持GET请求,所以抛去原生的网络缓存类,这里介绍一个比较好用的网络缓存策略

1.创建类继承自AFHTTPSessionManager,然后根据load方法等妙用,自动监测网络状态,获取网络状态后对其处理,有网加载,没网本地取出。

监测网络状态的方法我在上一篇文章中已经介绍了

GET和POST请求接口添加布尔属性,供选择是否选择对该URL缓存

3.每次调用请求接口,先在本地数据库读取缓存,如果本地没有再进行请求,请求完之后对其缓存。这里以```GET ```请求为例, ```POST ```请求也一样的逻辑。

4.提供清楚缓存和获取文件大小接口

评论(0) 浏览(28)

网站备案号:京ICP备11043289号-1 北京市公安局网络备案 海1101084571
版权所有 北京育灵童科技发展有限公司 Copyright © 2002-2019 www.elight.cn, All Rights Reserved