前言:

框架依旧在快速更新着:在重构、简化代码,统一标准的过程中。

中间也遇到各种坑,不过好在一步一脚印的解决了。

虽然还有些功能还在思考,不过教程,还是得补上:

上篇文章:Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页

里面讲到,引导完后,根据是否存在的Token来解决跳转到StartController还是MainController。

这篇就写写StartController,实现的代码虽少,但原理很精彩!!!

Sagit 实现登陆注册引导页

从WelcomleController中,现在跳到了StartController了:

呈现的内容如下图:(为不影响整体,这图宽高设的的很小,大伙可以新开窗口看大图):

这个界面,除了基础的布局,还有两个事件:

1:点立即注册:跳转到注册页。

2:点登录:或跳转到登录页。

整体的效果如下:

这里把View和Controller分开文件处理:

看看StartView的布局的全部代码:(下面是我本人简化后的代码,以前的代码多到吓死人)

  1. #import "STView.h"
  2.  
  3. @interface StartView : STView //StartView.h
  4.  
  5. @end
  6.  
  7. @implementation StartView //StartView.m
  8.  
  9. - (void)initUI
  10. {
      if(self.STController!=nil && self.STController.navigationController==nil){

[self.STController asRoot:RootViewNavigationType];}

  1. [self needNavigationBar:NO setNavBar:YES];//隐藏导航栏。
  2.  
  3. [[[self addImageView:@"logo" imgName:@"login_logo"] width: height:] relate:LeftTopRight v: v2: v3:];
  4.  
  5. UILabel *title = [[[self addLabel:nil text:@"IT恋" font:] width: height:] onBottom:@"logo" y:];
  6. [[title textColor:@"#000000"] textAlignment:NSTextAlignmentCenter];
  7.  
  8. UILabel *description = [[[[self addLabel:nil text:@"找优质靠谱IT男就上IT恋" font:] width: height:] onBottom:title y:] toCenter:X];
  9. [[description textColor:@"#000000"] textAlignment:NSTextAlignmentCenter];

  10. //框架调整,下面这几行代码有变化,具体见下文补充:
  11. UIButton *regBtn = [[[[self addButton:@"Reg" title:@"立即注册"] width: height:] onBottom:description y:] toCenter:X];
  12. [[regBtn backgroundImage:@"login_btn"] keyValue:@{@"leftNavImage":@"nav_arrow_left_black"}];
  13.  
  14. UIButton *loginBtn = [[[[self addButton:@"Login" title:@"已有账号,立即登录" font:] width: height:] onBottom:regBtn y:] toCenter:X];
  15. [[loginBtn titleColor:MainHexColor] keyValue:STPreView.keyValue];
  16. }
  17.  
  18. @end

新补充内容:

新变化的两行代码的写法(新的调整是为了可以控制导航栏的整体,包括标题及右边的样式【原来只能控制左侧】):

  1. [[[[this addButton:@"Reg" title:@"立即注册"] width: height:] onBottom:STPreView y:] toCenter:X];
  2. [[STLastButton backgroundImage:@"login_btn"] key:STNavConfig value:@{STNavTitle:@"账号注册",STNavLeftImage:@"nav_arrow_left_black"}];
  3.  
  4. [[[[this addButton:@"Login" title:@"已有账号,立即登录" font:] width: height:] onBottom:STPreView y:] toCenter:X];
  5. [[STLastButton titleColor:MainHexColor] block:nil on:^(UIView *view) {
  6. [view key:STNavConfig value:@{STNavTitle:@"登录",STNavLeftImage:@"nav_arrow_left_black"}];
  7. }];

代码功能讲解(第二点和第三点下面再细讲):

  1. :基本上一个控件布局就一行代码,直接看过去就好了。
  2.  
  3. :第一行设置不需要导航栏,并直接隐藏导航栏:[self needNavigationBar:NO setNavBar:YES];//隐藏导航栏
  4.  
  5. :注册和登陆按钮,多了一个陌生的keyValue,因为这里要控制导航的返回按钮为自定义的图片。

再看看StartController中的全部代码:

  1. @interface StartController : STController //StartController.h
    @end
  2.  
  3. @implementation StartController //StartContrller.m
  4.  
  5. -(instancetype)init
  6. {
  7. //初始化全局设置,必须要在UI初始之前。
  8. [self configNavAndStatusBar];
  9. return self;
  10. }
  11. -(void)configNavAndStatusBar
  12. {
  1. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];//白色底,所以状态字颜色改为黑
  2.  
  3. //这里提前统一设定全局协议的内容(对于登陆、注册、找回密码三个窗体有效),进入Main之后,会重新修改全局协议的内容
  4. [[[[[[UINavigationBar globalSetting] barTintColor:ColorWhite]tintColor:ColorBlack] backgroundImage:nil] shadowImage:nil]
  5. titleTextAttributes:@{NSForegroundColorAttributeName:ColorBlack}];
  1. }

功能讲解:

  1. 1:设置全局的导航栏和状态栏属性。
  2.  
  3. 2:如果当前不是导航控制器,则设置自身为导航根控制器。

Sagit 框架讲解:布局

对于框架的布局:

  1. :以【self addXXX】为起手势,一行代码实现一个UI的布局。
  2.  
  3. :对于需要特定类型的控制属性的,用变量接收后,用无限连语法处理属性赋值。
  4.  
  5. :相对父控件,用relate方法;相对同级,用:onToponLeftonRightonBottom方法,可以混着用,怎么简单怎么来。

布局的方法,都抽到了以下STUIViewAutoLayout文件中:

看看基本的方法重载:

  1. #pragma mark [相对布局方法] RelativeLayout
  2. -(UIView*)onRight:(id)uiOrName x:(CGFloat)x;
  3. -(UIView*)onRight:(id)uiOrName x:(CGFloat)x y:(CGFloat)y;
  4. -(UIView*)onLeft:(id)uiOrName x:(CGFloat)x;
  5. -(UIView*)onLeft:(id)uiOrName x:(CGFloat)x y:(CGFloat)y;
  6. -(UIView*)onTop:(id)uiOrName y:(CGFloat)y;
  7. -(UIView*)onTop:(id)uiOrName y:(CGFloat)y x:(CGFloat)x;
  8. -(UIView *)onBottom:(id)uiOrName y:(CGFloat)y;
  9. -(UIView *)onBottom:(id)uiOrName y:(CGFloat)y x:(CGFloat)x;
  10. -(UIView*)relate:(XYLocation)location v:(CGFloat)value;
  11. -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2;
  12. -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2 v3:(CGFloat)value3;
  13. -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2 v3:(CGFloat)value3 v4:(CGFloat)value4;
  14. -(UIView*)toCenter;
  15. -(UIView*)toCenter:(XYFlag)xyFlag;

这个很好理解的,基本读过去就明白了,简单易懂,其它的属性,等后续文章用到再说。

Sagit 框架讲解:事件

上一篇文章中,对事件有过一段讲解:

框架对于UIView扩展了两种点击事件的绑定方式:

  1. #pragma mark 扩展系统事件
  2. -(UIView*)click:(NSString*)event;
  3. - (UIView*)addClick:(onClick)block;

click用于指定一个事件的名称,addClick用于追加一个事件执行的代码块。

也说了事件的寻址流程:

  1. 1:先找传进来的event在所在的Controller中是否有对应的事件,若有,执行,若没有继续以下:
  2.  
  3. 2:对event追加后缀变成eventClickeventClick:再看有没有对应的事件,若有,执行,若没有继续以下:
  4.  
  5. 3:对event追加后缀变成EventController,看有没有对应的控制器,若有,执行默认的open:事件跳转,若没有,则无绑定事件。

不过上面的布局代码中并没使用click或addClick,同样是触发了这个流程:

核心就在于UIButtton的name,如果一个按钮有name,则寻找事件,如果找到,就自动绑定事件。

因此,对于两个name,Reg和Login:一路找到最终会找到RegController和LoginController,触发STController中预先定义的open:事件。

Sagit 框架讲解:keyValue属性和[UINavigationBar globalSetting]

1:keyValue属性

IT恋这里有点特殊,跳转后需要改变导航栏的返回图标,原来在Controller中写事件:

[self stPush:方法的第三个参数,指定一张图片做为返回按钮]

不过对于有代码洁P的我,总想着怎么消灭掉这些这些代码,虽然两个事件就几行,但也不留。

这个参数怎么传到open:里呢?如果不是图片,是指定文字为返回的按钮呢?

最后想到一个相对完美的解决方案:

1:对UIView再扩展了一个keyValue的属性,于是有了:

keyValue已升级:新的写法见上面的补充代码。

  1. [[regBtn backgroundImage:@"login_btn"] keyValue:@{@"leftNavImage":@"nav_arrow_left_black"}];//这是旧代码,已过期不能用

2:open:事件中,再进行一下的简单判断拿值(这里也已经调整过)。

就这样完美的解决了。

后来发现这个keyValue还有更多的用户场景,如:设置控制导航栏的显示或隐藏:

  1. [self needNavigationBar:NO setNavBar:YES];//隐藏导航栏。

内部其实就是对keyValue进行取值或赋值:

  1. -(UIView*)needNavigationBar:(BOOL)yesNo setNavBar:(BOOL)setNavBar
  2. {
  3. if(self.keyValue==nil)
  4. {
  5. self.keyValue=[NSMutableDictionary new];
  6. }
  7. [self.keyValue set:@"needNavigationBar" value:yesNo?@"":@""];
  8. if(setNavBar && self.STController!=nil && self.STController.navigationController!=nil)
  9. {
  10. self.STController.navigationController.navigationBar.hidden=!yesNo;
  11. }
  12. return self;
  13. }

目前框架是自动控制导航栏的显示或隐藏,不需要用户去再操心的在每个页面都是写代码了。

为了这个导航栏,真花我不少心力,特别是自定义返回和系统滑动返回,研究的过程都够另外再写一篇。

2:UINavigationBar globalSetting 的产生:

A:对于这个StartController这个页面,有以下几种情况会跳转过来:

  1. :从欢迎引导页WelcomeController进来;
  2.  
  3. :用户进行系统后,点击退出时从SystemController进来;
  4.  
  5. :当前用户的Token数据失效,需要重新登陆时,从MainController中,跳进来;

不管从哪个地方过来,由于自身需要占根视图,而为导航控制器,所以有一行代码:

  1. //从引导页跳转来时,需要将自身设置为导航根控制器
  2. if(self.STController.navigationController==nil){[self.STController asRoot:RootViewNavigationType];}

框架对UIViewCtroller扩展了:asRoot方法,可以将当前Controller直接设置为根视图:

  1. //将当前视图设置为根视图
  2. -(UIViewController*)asRoot:(RootViewControllerType)rootViewControllerType{
  3.  
  4. UIViewController *controller=self;
  5. if(rootViewControllerType==RootViewNavigationType)
  6. {
  7. controller = [[UINavigationController alloc]initWithRootViewController:self];
  8. //self.navigationController.navigationBar.hidden=!self.view.needNavigationBar;
  9. }
  10. [UIApplication sharedApplication].delegate.window.rootViewController=controller;
  11. return self;
  12. }

B:导航栏进行统一的颜色风格处理(处理后,将对注册、登陆、找回密码等生效):

之前的代码是这样的:

框架封装完成属性无限连后可以这样:

  1. [[[[[[UINavigationBar globalSetting] barTintColor:ColorWhite]tintColor:ColorBlack] backgroundImage:nil] shadowImage:nil]
  2. titleTextAttributes:@{NSForegroundColorAttributeName:ColorBlack}];

这里有几点坑和大伙分享:

坑A:如何进行属性无限连

[UINavigationBar appearance] 这里返回的是协议接口,并不是UINavigationBar实例

一开始看到UINavigationBar去接收appearance的属性,聪明如我,就去扩展UINavigationBar的属性方法,然后打算用无限连简化。

结果一运行就死,进入坑里徘徊了不少时间,最后才发现appearance返回的是UIAppearance接口,并不是UINavigationBar类型。

但是UIAppearnce又不能直接用,也不能对协议接口做扩展,一时蒙了下B。

然后绕到导航栏显示不显示、自定义返回和滑动返回,返回主界面没主动往上顶等坑里。

坑里呆久出来后,想到另一种方式来实现无限连:

通过一个静态方法返回一个自定义类,再由这个自定义类来连代码,像这样:

  1. @implementation UINavigationBar (ST)
  2.  
  3. +(UINavigationBarSetting*)globalSetting
  4. {
  5. return [UINavigationBarSetting new];
  6. }
  7. @end
  8.  
  9. @implementation UINavigationBarSetting
  10. #pragma mark 扩展系统属性
  11. -(UINavigationBarSetting*)tintColor:(id)colorOrHex
  12. {
  13. [UINavigationBar appearance].tintColor=[UIView toColor:(colorOrHex)];
  14. return self;
  15. }
  16. -(UINavigationBarSetting*)barTintColor:(id)colorOrHex
  17. {
  18. [UINavigationBar appearance].barTintColor=[UIView toColor:(colorOrHex)];
  19. return self;
  20. }

坑B:为何全局设置无效

以前的代码,先执行ViewDidLoad里的全局设置,再执行asRoot,触发导航栏,这样是正常的:

  1. -(void)viewWillAppear:(BOOL)animated
  2. {
  3. if(self.navigationController==nil)
  4. {
  5. [self asRoot:RootViewNavigationType];
  6. //self.navigationController.navigationBar.hidden = YES;
  7. }
  8. }

但是这段代码被我消灭了,其它地方的跳转代码都是直接,退出后转跳:

改完后,发现全局失效了,最后坑里呆了一圈才发现:

全局的设置,必须在导航栏UI出现之前设置才有效,所以,如果这样写代码:

全局设置就不能写在ViewDidLoad里了,必须写在init中了。

总结:

1:用框架写代码很简单,也很简洁。

2:框架目前的代码不多,早看早了结。

3:随着应用场景的增多,框架会不断的增强,预味着开发仍是很简单,但要理解原理就需要花更多时间。

4:虽然教程是以IT恋为讲解,但还是希望大伙多关心IT连,哈。

Sagit.Framework For IOS 开发框架入门教程3:Start引导页及框架布局和隐藏事件的内幕的更多相关文章

  1. Sagit.Framework For IOS 开发框架入门教程4:注册页布局-被消灭的变量

    前言: 上篇写完:Sagit.Framework For IOS 开发框架入门教程3:Start引导页-框架布局和隐藏事件的内幕 之后,好久没写文章了,有IT连创业系列.有DotNetCore的一篇文 ...

  2. Sagit.Framework For IOS 开发框架入门教程6:网络请求STHttp

    前言: IOS的文章,今天,再来补一篇,Sagit的教程: 虽然感觉IOS的文章没什么观众,还是努力写吧,-_-〜 Sagit 开源地址:https://github.com/cyq1162/Sagi ...

  3. Sagit.Framework For IOS 开发框架入门教程5:消息弹窗STMsgBox

    前言: 昨天刚写了一篇IT连创业的文章:IT连创业系列:产品设计之答题模块,(欢迎大伙关注!) 感觉好久没写IOS的文章了,今天趁机,来补一篇,Sagit的教程. Sagit 开源地址:https:/ ...

  4. Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页

    前言: 开篇比较简单:Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置 第二篇教程之前写了一半,感觉不太好写,而且内容单纯介绍API,要说的很多,又枯燥乏味. ...

  5. Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置

    背景: 前天开源了框架:开源:Sagit.Framework For IOS 开发框架 所以注定要追补一套开发教程了,所以尽量抽空了!!! 步骤 1:下载框架源码 GitHub:https://git ...

  6. 开源:Sagit.Framework For IOS 开发框架

    一:创造Sagit开发框架的起因: 记得IT连创业刚进行时,招了个IOS的女生做开发,然后: ----------女生的事故就此开始了----------- 1:面试时候:有作品,态度也不错,感觉应该 ...

  7. iOS开发入门教程

    iOS开发入门教程 http://my.oschina.net/mailzwj/blog/133273 摘要 iOS开发入门教程,从创建项目到运行项目,包括OC基础,调试,模拟器设置等相关知识. iO ...

  8. [置顶] IOS 基础入门教程

    IOS 基础入门教程 教程列表: IOS 简介 IOS环境搭建 Objective C 基础知识 创建第一款iPhone应用程序 IOS操作(action)和输出口(Outlet) iOS - 委托( ...

  9. Apple官方IOS开发入门教程[v0.2]

    今天,又跑去找IOS开发入门教程了,结果发现没什么好的PDF. 后来发现,原来苹果官方有开发入门教程,而且写的很好.所以整理出来了,给大家分享一下. 我就不在这里贴pdf的内容了,下面有苹果官方教程的 ...

随机推荐

  1. 0_Simple__clock + 0_Simple__clock_nvrtc

    使用 clock() 函数在CUDA核函数内部进行计时,将核函数封装为PTX并在另外的代码中读取和使用. ▶ 源代码:文件内建核函数计时. #include <stdio.h> #incl ...

  2. Javascript下IE与Firefox下的差异兼容写法总结

    http://www.jb51.net/article/23923.htm     总结一部分IE和Firefox的javascript差异写法,对于像书写多浏览器兼容性更好的代码,可以参考下.   ...

  3. 启动Apache出现问题:一直停留在启动界面

    问题描述:  由于需要php_curl模块,因此直接在php.ini文件将前面的分号去掉  ,但是重启Apache时出现:一直停留在启动界面,Apache无法正常启动,查看错误日志,显示如下: 解决方 ...

  4. eclipse导出jar(含依赖)三步走

    之前用eclipse导出jar运行结果一直不尽人意,排查问题排查很久,最终确定到导出jar时,如果依赖jdk以外的jar时,就要通知eclipse 看了很多帖子,感觉操作起来都比较麻烦,注意点也比较多 ...

  5. QT制作窗口切换的小程序

    前言:本次实验是在三个窗口之间自由切换,窗口中播放gif格式的动态图. 让我们先来看看使用到的主要的函数: 一.播放gif格式动态图的函数 QMovie *movie = new QMovie(&qu ...

  6. 记录一次Session偶尔获取不到的解决过程

    导读 平台下某子系统有密码登录需求,初步考虑用Session,登录后设置Session[key]=value;Session中若某key对应的Session,即Session[key]为null则限制 ...

  7. [转载] redis-cluster研究和使用

    转载自http://hot66hot.iteye.com/blog/2050676 最近研究redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 release ...

  8. Git命令补全配置

    Git命令补全功能 1.下载下面的文件 https://github.com/sguo421/code/blob/master/git-completion.bash 2.放倒HOME目录下,设置为隐 ...

  9. iOS 远程推送消息解析及逻辑处理

    关于远程推送的相关配置网上已经有足够多的教程,这里就不复述了.这里讲述当客户端收到推送消息后,应怎样对其进行相应的逻辑处理. 工程的AppDelegate.m文件里提供了如下方法: //当应用程序启动 ...

  10. 自动化之路 python psutil模块 收集硬件信息

    一.psutil模块 1. psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控,分析和限制系统资源及进程的管理.它实现了 ...