百思不得姐第3天:登录注册界面搭建

Posted Hello_IOS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了百思不得姐第3天:登录注册界面搭建相关的知识,希望对你有一定的参考价值。

一:登录注册的界面效果如图

技术分享技术分享

技术分享

技术分享

二:界面的搭建

1:登陆界面一般都是moda的模式:新建控制器,勾选xib,则系统会自动关联类,并且自动连线关联view(若是后创建的控制器的xib,则类名相同,关联类,在fileOwer处连线view),而我们自己不用去设置控制器view的frame。或是freeform,只需要更改控制器view的尺寸,例如4.7寸,那么在别的机型上运行正常适配。2:一般背景比较好看的都为背景图片。 3:控制状态栏的样式:1:[UIApplication sharedApplication].statusBarStyle; 设置全局状态的导航栏,还需要配置plist ,设置view controller base 为 no(不推荐) 2:从ios7开始就可以在控制器内,设值状态栏。- (UIStatusBarStyle)preferredStatusBarStyle

{    return UIStatusBarStyleLightContent;}

两者设置其一,则另一个就不管用,不推荐使用第一种,默认颜色为黑色。2:隐藏状态栏:- (BOOL)prefersStatusBarHidden 若是配置了pills,则用[UIApplication sharedApplication].statusBar hidden

2:登录界面的UI分析:1:控制器或是view,要想到分层封装思想(参照新浪微博cell的封装),将控制器或是view切分成一个个模块,分析每个模块都由哪些控件组成,将零散的控件都封装在一个统一的模块内部(具体参照view的方法),再看封装的每一个模块的内部view是否还可以继续封装,然后再看封装的view,是否项目中的其他地方也可以用到,若是可以,则想到继承,将公共部分抽成父类,子类去继承父类,不同的部分在子类中实现,1:父类可在.h中暴露方法,再在.m中实现该方法,则子类也继承了父类的方法,当子类调用父类的方法的时候,就会调用父类的实现方法 (新浪微博参数模型的抽父类继承)2:若是有多个子类继承同一个父类的时候,在父类中父类要根据不同的子类来执行不同的方法,此时父类可提供一个标识的属性方法供子类继承重写其get方法,此时在父类中就可以区别不同的子类了(百思的主界面继承结构)3:若是父类提供了某个方法,父类也实现了该方法,则子类继承该方法后,继续重写该方法,1:若是不保留父类行为,可以不调用super。 2:调用代码写在super之上,重写setframe方法,重新设计参数传入super方法 3:写在super之下,则先是保留父类的行为,在设置子类的行为 2:如图的登陆界面,则封装成三个view,上部一个view,中间一个view,底部一个view,而对于底部的view,也可以封装成两个view,上部一个view,底部一个view,底部的view中的按钮又可以继续去封装  3:当拷贝xib中已经设置好的约束控件后,只会拷贝宽高约束,其他约束不会拷贝。如图:中间为lable,两边为uimageView

技术分享

补充:1:新浪微博cell的封装MVVM思想:1:封装的背景view0直接添加到cell上,又将微博正文view1 与 底部工具条 view2,封装起来添加到view0上,底部的工具条view2封装为一个整体view2,微博正文的view1的层级机构为原创微博view3与转发微博的view4,将头像昵称时间皇冠,微博内容,图片等信息都封装在原创微博的view3里,其中微博的图片又封装了一层view5,专门用来显示图片,被转发微博的微博正文和图片都添加到view4上。注意:不管有没有显示,先将尽可能显示的控件全部都添加到封装的view中,再根据数据模型model的字段值来判断让控件显示还是隐藏,要考虑到cell的循环利用(显示了,还要隐藏回来),避免因为cell的复用出现数据错乱。2:MVVM思想:把cellFrame封装为一个数据模型,在cellFrame数据模型的内部status数据模型作为cellFrame数据模型的属性,根据status数据模型的字段值来设置给个控件的frame,cellFrame的好处:既可以为控件设置frame,又可以为控件设置属性值。而每一个封装的view都对应一个cellFrame模型,在控制器内部的数据源也是存放的cellFrame的数据模型。MVVM思想层次结构更加清晰,大量简化了控制器的代码便于维护 3:如何设置cell的高度:1:在cell中设置:在cell中提供类方法传入每行row对应的数据模型,根据数据模型的字段值计算出总的cell的高度 2:在model中提供高度的属性,在model中重写get方法,根据model中的字段值计算总的cell的高度,为了优化,还可以设置内存缓存,当计算过cell的高度后让其直接返回,不再执行计算高度的方法。(推荐第二种)

      2:view的封装方法:无论是代码还是xib都要想到模块化分层封装的思想。

1:instanceType方法提供类方法快速返回对象,1:内部调用alloc init ,alloc init内部调用[alloc  initWithFrame ]方法,[super  initWithFrame ]会调用setFrame方法,可以重写setFrame方法来设置自身固定的frame,禁止外界更改,还可以重写setFrame设置cell的上下左右的间距,分割线等,当外界设置frame的时候,又会调用setFrame方法,当setFrame方法调用完毕后,才会调用layoutSubview方法来设置frame 2:可以在[alloc  initWithFrame ]方法中设置自身封装view的一些特定属性,或是一次性代码 2:懒加载子控件:(懒加载的作用:1:不用考虑代码的创建顺序 2:保证只初始化一次  3:懒加载可用weak 和 strong 都可以)在懒加载的方法中设置子控件的属性,并将子控件添加到父控件上。

2:重写layoutSubView方法设置子控件的frame:在此方法内设置子控件的frame较为准确严谨,不要忘记调用super,且此方法配合setNeedsLayout和layoutIfneed配合使用:前者是异步调用layoutSubView方法,而后者layoutIfneed是立即调用layoutSubView方法来更新约束。1:如何拿到控件:1:属性,成员变量,枚举tag值(1:直接取,2:或是遍历父控件的子控件数组,通过tag值取出,tag值一般不要设为0,不安全,因为所有控件默认的tag值都为0 3:一般在设置tag值的时候通过self.subviews,count 也可以设置tag值),或是继承父类直接从父类属性获取   2:将创建的控件放在一个属性定义的大数组中,若是含有不同类的控件则两两放在大数组中,在layoutSubView里通过for循环从数组中取出子控件 3:遍历父控件的子控件数组:1:self.subViews(UIView和scroll隐藏掉两个滚动条后是最纯洁的view,除了自己添加的不含有任何 子控件,所以可以直接遍历父控件的子控件数组),需要index就采用int i 遍历,不需要就可以采用for in快速遍历,并在外部定义index,内部index++,来记录索引值,也可以用enumer来遍历可以得到索引值和遍历的对象。在遍历时,先要做条件过滤(1:continue 2:return过滤,不执行return下面的代码,3:break,跳出循环,不再循环)找到后设置值,并停止遍历 2:若是遍历父控件的self.subViews子控件数组,有时候系统父控件没有直接提供属性使用,这时,可以打印子控件数组或是通过ViewUI来调 试查看所需要的子控件是什么,这样就可以拿到子控件从字符串转化为类,NSClassFromString()(新浪设置中间加号按钮)3:利用runtime拿到系统控件私有的属性来进行设置

3:为封装view设计model接口与业务逻辑接口:设计model接口,重写model的set方法,为封装view的子控件赋值。业务逻辑的接口设计:1:把与外界无关的业务逻辑全部封装在类的内部,类再提供接口供外界访问,保证外界调用时最简洁最方便的的 2:对于接口的设计:一般用属性接口重写通过重写代替方法接口,是否就提供BOOL属性接口,不同类型,就提供枚举type接口,外界想访问类内部的什么方法,变量就给外部提供属性接口。

4:业务逻辑的监听处理:1:查看子类有没有系统代理方法,通知方法,或是继承UIControl的可以addTarget都可以实现监听,若是子类没有还可以查看父类有没有上述 的方法,在查看系统的API时,可以查看其其英文注释该方法的使用说明,也可以按住option键点击某个方法来查看使用说明 2:通过重写监听:在开发中遇到问题首先考虑重写,重写非常好用,继承父类,通过重写父类的方法也可以对父类行为进行拦截,覆盖或是监听父类的行为。但是不要忘记调用super, 否则父类的默认行为就不会响应。3:当监听自身的属性变化的时候,可以使用kvo实现监听,当属性变化的时候可以去实现某些方法

 5:监听回调:1:层级较浅时,用协议代理(1:仿照tableView的代理方法设计协议代理 2:有时需要重写setDelegate方法来,也就是成为代理之后才可以去做某些设置)block,两者都可以,当两个类需要相互回调时,可以给协议代 理或是block设置返回值,就可以实现两个类相互回调 2:层级较深的时候:可以利用通知回调,传值,其中通知可以在当前线程或是子线程中执行(只看post通知的时候在哪个线程里,注册观察者后,执行通知方 法就在哪个线程),其中注册观察者也可以用block方式注册观察者,并指定收到通知后的block任务在哪个线程中执行(也可实现一次性的通知,在 block中执行完任务后,就取消观察者),如果采用block的方式注册的观察者,要以熟悉定义id类型返回值类接受block通知的返回值,以便在 dealloc中注销观察者。一般项目中的通知名都写在配置常量的类里  

6:考虑继承关系:若是封装的该view在项目中其他的地方也可以用到,则考虑用继承,将相同的部分抽成父类,让子类去继承,不同的部分在子类中实现,父类可以给子类提供方法供子类去重写,实现父类和子类相互的关联

7:问题分析:当系统提供的控件不能满足我们的要求的时候,我们可以选择自定义控件,自定义控件继承系统的控件,1:重写layoutSubView方法,1:在该方法内部直接拿到系统的控件去设置 2:如果不能直接拿到系统的子控件,在该方法内部遍历系统控件的子控件数组,并打印或是通过viewUI来调试查看子控件,再通过NSClassFromString来进行设置 3:利用runtime拿到系统控件内部私有的成员变量去设置(更改文本框的占位文字颜色)2:通过继承关系,自定义控件的子类重写父类的方法,super的调用三种情况。通过重写父类的方法可以实现对父类行为的监听,覆盖,修改  3:还可以为系统的类写分类,在分类中提供方法

 

3:控制器中代码的规范:1:先分析界面的UI,分析好界面的封装结构,先要整理好逻辑,把逻辑理顺了,再去下手去写代码 2:1:在控制器中实现+(void)load,做一些常用配置(例如配置MJExtension字典转模型的配置),不管有没有子类,该方法只执行一次,并且不用导入头文件 就可以调用,也就是该类被加载进内存就会调用 +(void)initalize该方法可能会被调用多次,当类被初始的时候会被调用,当有子类的时候,会先调用父类的+(void)initalize方法,在调用子类的+(void)initalize方法(父类中重写了+(void)initalize方法,子类继承,没有重写),在该方法中可以初始化一些配 置的设置或是只需要一次性设置的(自定义导航控制器设置全局导航主题,或是数据库建表)重写控制器的init方法,可以在控制器创建初始化时传递参数或是 初始化时做一些固定的一次性设置,例如设置tableView的样式可以在初始化的时候调用,当控制器初始化的时候会调用控制器的init方法。-(void)loadView方法,重写此方法可以更改控制器的self.view  viewDidLoad方法view加载完毕后调用,viewWillAppear 或是viewWillDidAppear 这两个方法会调用不止一次,只要是界面出现即将出现就会调用,pop,dissmiss都会调用,一般在viewDidAppear方法中打印控件 的信息,因为此时控件已经完全显示出来,viewWillDisappear,viewDiddisappear页面即将消失或是已经消失 的时候调用,dealloc控制器销毁的时候调用,在此方法中可以移除通知或是在控制器销毁的时候传递给其他控制器一些数据信息。2:我们一般在 viewDidLoad方法中采取封装方法调用 1:当控制器中某个方法含有大量重复的代码时要考虑抽方法封装,将相同的代码抽到方法的内部,不同的部分作为参数传递 2:若是代码中涉及某些业务逻辑的处理或是项目中各个地方都可以用到,则也应考虑到封装:1:分类封装:1:当此段业务逻辑与系统某个类有关系时,要想到 给系统类写分类,而且能写分类尽量写分类,因为分类会少创建类,减少内存 2:分类的接口设计:对象方法或是类方法,类方法较对象方法简餐粗暴,但是当需要传递两个参数的时候可以考虑利用对象方法,分类中的self指的就是传递 的参数 ,若是在分类中以属性定义变量,则只会生成set和get的声明,不会生成实现也不会生成带下划线的成员变量,若是此时外界想要访问分类某个变量则可以用static定义的全局变量 在get方法中返回就可以了 2:管理类Tool封装:单例或是类方法,在类方法中要是想获得单例一样的成员变量,就用static定义全局变量,该成员变量也可以采用懒加载模式,只 让其初始化一次,外界若是想访问该成员变量,则该类可以提供接口get方法接口,供外界调用(get方法接口也可以用点语法去调用)3:考虑继承:将相同 的部分抽到父类,不同的部分分别在子类中去实现,父类可在.h中暴露方法供子类去重写(父类可提供标识属性,供子类去重写,以便于在父类中区分不同子 类),子类重写父类的方法后,也就相当于间接修改了父类的属性,父类中也就可以拿到子类修改的属性。3:控制器或是view中每一行代码的编写,都要力求 使最简洁的,要反复推敲,提炼,直到代码是最简洁不能再抽为止。1:像是hidden或是返回bool值的方法中一句代码解决 或是利用三目运算简化ifelse 2:赋值散三部,最上面定位nil,中间赋值,最后赋值 3:有两个返回值时,只用一个if,分别返回,不用if else 4:当遍历的时候,先做条件过滤(continue,braek,或是return条件过滤),找到赋值,并停止遍历。 

 

以上是关于百思不得姐第3天:登录注册界面搭建的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio实现QQ的注册登录和好友列表界面的跳转

Android Studio实现QQ的注册登录和好友列表之间的跳转

Flask实战第45天:完成前台登录界面

Android Studio学习第一篇制作一个拥有登录和注册功能的简易APP

PyQt5实现登录界面,包含用户注册,记住密码功能

PyQt5实现登录界面,包含用户注册,记住密码功能