一:访客界面效果如图

二:xib封装访客视图的view

1:业务逻辑分析:1:由于用户未登录时要显示访客视图,要先进行判断用户是否登录,未登录则显示访客视图,登录则显示正常的登陆界面,由于要在四个子控制器界面的控制器中都要判断是否显示访客视图,同样的逻辑,所以考虑抽成父类,把判断是否显示访客视图的逻辑封装在父类中,让子类去继承。2:访客视图的界面如图:将访客视图封装在一个view中,view的界面相对固定,所以用xib搭建,首先将尽可能显示的控件全部封装在view的内部,再根据外界传入的model或是在封装类中定义方法来控制控件显示的内容或是相应控件的显示和隐藏,3:通过在父类控制器中重写loadView方法判断用户是否登陆来设置是否加载访客视图

2:访客视图的搭建:新建文件继承UIView,新建xib与新建的UIview类同名,首先来到xib中,将类与xib进行关联,可以不设置freeform

1:1:先拖入UIimageView来设置旋转图片:先在如图处设置xib约束,设置控件相对于父视图水平居中竖直居中,在如图所示位置水平竖直居中(此处1设置的是相对于父视图的水平竖直居中,图2水平竖直居中对齐,一般都是任意选中两个控件,设置控件A相对于控件B的中心点水平竖直居中)。

2:先设置旋转图片相对于父视图水平竖直居中,在上图1中去设置,再来到右侧调整其竖直中心点向上偏移,按住command + =调整旋转图片的UIimageView的大小等于图片的大小,就不用再去设置宽高的约束了。

3:再拖入一个UIImageView背景图片来盖住旋转图片的底部,在如图所示的位置设置背景图片的顶部左右和高约束,(图中小箭头的部分可以设置相对于哪个控件的约束)

4:再设置房子的约束,拖入一个UIimageView,command + = 来设置imageView的大小和图片的大小相等,所以就不用设置宽高约束了,再来到如图所示的位置处设置,同时选中房子和旋转图片,拉线,按住shift键可同时设置多个约束,设置房子相对于旋转view的中心点水平居中,竖直居中(在右侧又可以调整位置的相对偏移)

5:提示lable的约束设置:拖入lable,换行,设置numberoflines为0,设置文字的居中效果,Aliment对齐方式为居中,就会显示出如图所示的效果:在左侧同时选中lable和房子,设置lable相对于房子中心点水平居中对齐,y方向的约束就设置lable距离房子底部的约束,拉线设置竖直距离。给lable设置一个最大宽度的约束,为了适配登陆注册按钮,高度约束不去设置

10:登陆注册按钮的设置:拖入注册按钮,调整样式为custom,否则不能显示出按钮的高亮状态,设置按钮的背景图片,此时背景图片会拉伸,可以在如图处设置,防止注册按钮的背景拉伸:在如图出sliciing处设置水平竖直为保护区域,不产生拉伸

宽高约束不设置,让按钮根据内容大小来自定义宽高,在设置按钮相对lable左对齐,y方向约束,设置lable相对于房子(固定不变)的底部约束,为了避免因提示文字内容的多少,而导致四个界面的登陆注册按钮不再同一个y值方向上。再拷贝粘贴出登陆按钮,拷贝粘贴的控件保留了宽高约束,所以还需要设置其右对齐和y方向上的约束。设置两个控件的对齐方式如图:1:同时选中两个控件,来到如图处位置设置两个控件的对齐方式

三:控制器代码

1:封装访客view的代码

import UIKit
/*总结:1:设置好xib后,拉线到相应的view中成为RHVisitorView的属性(对于注释:一般代码的模块化用 //MARK:-1来注释,非模块化只是可用//来表示),@IBOutlet weak var loginBtn: UIButton!,用weak修饰因为xib控件已经在该view上了,所以该view对该控件已经有了一个强引用,在swift中一般变量基本都为可选类型,要是确定其一定有值,则可以用!来进行强制解包,as?可以将左边的类型转换为右边的可选类型,as!当确定要转的变量一定有值的时候,可以将左边的可选类型转换为右边确定的类型,as,将左边的类型转换为右边的类型,例如:利用as将swift字符串转为oc字符串来实现字符串的截取2:1:在封装的view中提供类方法快速返回xib中加载的对象:在swift中类方法以class开头:class + func + 函数名(参数裂变)-> 返回值类型{业务逻辑代码return 返回值类型}2:代码class func visitorView()-> RHVisitorView{//1:加载xib的viewlet visitor = Bundle.main.loadNibNamed("RHVisitorView", owner: nil, options: nil)!.last as! RHVisitorViewvisitor.backgroundColor = UIColor(red: 238/255.0, green: 238/255.0, blue: 238/255.0, alpha: 1)return visitor}1:Bundle.main.loadNibNamed("RHVisitorView", owner: nil, options: nil),从xib中获得加载的数组,此获得数组的类型为可选类型[Any]?,Any表示数组中存放的元素,此时可以保证数组一定有值,所以可以!强制解包, Bundle.main.loadNibNamed("RHVisitorView", owner: nil, options: nil)!2:Bundle.main.loadNibNamed("RHVisitorView", owner: nil, options: nil)!.last,从数组或是字典取出的元素都是Any?的可选类型,能保证其一定有值,可以用as!转换为RHVisitorView类型3:封装view提供方法接口来控制封装view具体显示的内容和需要隐藏的内容:1:传入参数imageName和title来设置图片和文字的显示内容,其中苹果默认函数中第一个参数为内部参数,用_+空格+参数名来表示,默认从第二个参数开始即为内部参数又为外部参数,要想让其他参数,也为默认参数则可以用_+空格+参数名来表示,还可以传入默认参数。4:首页需要旋转图片:旋转图片绕着z轴旋转一圈2π,从0到2π,两个value值,所以用CABasicAnimationfunc rotationImage() {//1:创建基础动画对象let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")//2:设置动画效果rotationAnimation.fromValue = 0rotationAnimation.toValue = M_PI * 2rotationAnimation.repeatCount = MAXFLOATrotationAnimation.isRemovedOnCompletion = falserotationAnimation.duration = 3//3:将动画添加到layear上rotationImageView.layer.add(rotationAnimation, forKey: nil)}注意:1:核心动画,都会在切换界面或是程序进入后台的时候停止动画,所以rotationAnimation.isRemovedOnCompletion = false2:要将核心动画添加到view的layer上**/
class RHVisitorView: UIView {//MARK:-1:定义xib属性@IBOutlet weak var loginBtn: UIButton!@IBOutlet weak var infoLable: UILabel!@IBOutlet weak var registerBtn: UIButton!@IBOutlet weak var rotationImageView: UIImageView!@IBOutlet weak var iconImageView: UIImageView!//MARK:-2:类方法加载xib并设置背景色class func visitorView()-> RHVisitorView{//1:加载xib的viewlet visitor = Bundle.main.loadNibNamed("RHVisitorView", owner: nil, options: nil)!.last as! RHVisitorViewvisitor.backgroundColor = UIColor(red: 238/255.0, green: 238/255.0, blue: 238/255.0, alpha: 1)return visitor}//MARK:-3:提供接口,供子类调用
    func setupVisitorView(_ imageName:String,title:String) {iconImageView.image = UIImage(named: imageName)infoLable.text = titlerotationImageView.isHidden = true}//MARK:-4:旋转图片
    func rotationImage() {//1:创建基础动画对象let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")//2:设置动画效果rotationAnimation.fromValue = 0rotationAnimation.toValue = M_PI * 2rotationAnimation.repeatCount = MAXFLOATrotationAnimation.isRemovedOnCompletion = falserotationAnimation.duration = 3//3:将动画添加到layear上
        rotationImageView.layer.add(rotationAnimation, forKey: nil)}}

2:父类控制器代码

import UIKit
/*总结:1:为什么要抽父类RHBaseTableViewController?因为要显示访客视图就要判断用户是否登陆,四个控制器界面都需要判断,所以可以将四个界面相同的业务逻辑抽到父类,让子类去继承(若是将业务逻辑封装在工具类中,四个界面依然需要写相同的代码,所以考虑抽到父类,让子类去继承)四个界面的访客视图界面又是类似,所以可以将访客视图的界面也封装在父类中,访客视图封装时把尽可能显示的控件全部添加到视图中,然后父类提供访客视图的接口,让子类去继承,访客视图中再去封装方法来控制不同界面访客视图的显示和隐藏2:在父类中定义属性标识来判断用户是否登陆:1:在类中定义属性的时候,必须给属性一个初始值,或是定义为可选类型,在之后初始化或是其他地方再给该属性赋值,Bool属性只有两个关键字true和false 2:懒加载:1:闭包懒加载 2:直接进行初始化 注意:1:懒加载用关键字lazy并且必须是var来修饰 2:在定义类属性或是懒加载或是定义类中方法的时候,要考虑是否需要用private或是filePrivate来修饰来保证私有不让外界访问,private,只在当前的class类中可以访问,在同一个文件中不同class类中不可以访问,filePrivate在当前文件任何地方都可以访问,二者都不能在外界被访问3: 设置访客视图需要重写控制器的方法loadView,在此方法中可以设置控制器当前的view,当我们需要重写系统的方法的时候,需要加上override重写标识,用三目运算,根据是否登陆的表示,来选择加载不同的控制器的view,setupView()方法是创建访客视图的方法,一般将此方法都封装在当前类的扩展中extensionoverride func loadView() {//1:根据标识判断是加载访客视图还是登陆后界面isLogin ? super.loadView() : setupView()}4: //MARK:-4:设置访客视图的viewextension RHBaseTableViewController {fileprivate func setupView() {view = visitorView}},fileprivate设置该方法为私有,外界不可以访问5:在viewDidLoad中设置左右导航栏按钮:将设置导航栏左右按钮也封装在当前类中的extension中,在当前类中调用当前类的方法可以省去self://注册按钮navigationItem.leftBarButtonItem = UIBarButtonItem(title: "注册", style: .plain, target: self, action: #selector(RHBaseTableViewController.clickRegisterBtn))事件监听:#selector(RHBaseTableViewController.clickRegisterBtn),一般也将事件的监听封装在当前类的extension中,  当监听点击事件的时候,才用 @objc,当swift中定义的方法用private或是fileprivate修饰的时候,则不会将该方法加载进类的方法列表,用@objc则会将该方法依然加入到方法列表中extension RHBaseTableViewController {@objc fileprivate func clickRegisterBtn() {DLog(message: "点击了左侧的注册按钮")}6:访客视图中的登陆注册按钮的监听:1:若是将监听方法放在访客视图的view中则需要协议代理,通知,闭包来进行反向监听,还可以在访客视图中提供两个btn的属性接口,在父类控制器中来设置监听,在父类的控制器中来实现跳转**/class RHBaseTableViewController: UITableViewController {//MARK:-1:定义属性标识:用来判断是显示访客视图还是登陆界面,默认是没有登陆let isLogin = falselazy var visitorView = RHVisitorView.visitorView()//MARK:-2:设置访客视图:重写loadView方法,从而更改当前控制器的viewoverride func loadView() {//1:根据标识判断是加载访客视图还是登陆后界面
        isLogin ? super.loadView() : setupView()}override func viewDidLoad() {super.viewDidLoad()//MARK:-3:设置左右按钮的导航栏
        setupNavgationItem()//MARK:-4:添加登录注册按钮监听//注册按钮visitorView.registerBtn.addTarget(self, action: #selector(registBtnClick), for: .touchUpInside)//登录按钮visitorView.loginBtn.addTarget(self, action: #selector(loginBtnClic), for: .touchUpInside)}
}//MARK:-4:设置访客视图的view
extension RHBaseTableViewController {fileprivate func setupView() {view = visitorView}
}//MARK:-5:设置导航栏左右item
extension RHBaseTableViewController {fileprivate func setupNavgationItem() {//注册按钮navigationItem.leftBarButtonItem = UIBarButtonItem(title: "注册", style: .plain, target: self, action: #selector(RHBaseTableViewController.clickRegisterBtn))//登录按钮navigationItem.rightBarButtonItem = UIBarButtonItem(title: "登录", style: .plain, target: self, action: #selector(RHBaseTableViewController.clickLoginBtn))}}//MARK:-6:监听按钮的点击
extension RHBaseTableViewController {@objc fileprivate func clickRegisterBtn() {DLog(message: "点击了左侧的注册按钮")}@objc fileprivate func clickLoginBtn() {DLog(message: "点击了右侧的登录按钮")}@objc fileprivate func registBtnClick() {DLog(message: "点击了注册按钮")}@objc fileprivate func loginBtnClic() {DLog(message: "点击了登录按钮")}
}

3:Appdelegate中设置Navbar的渲染

import UIKit@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {//MARK:-1:设置全局tab渲染颜色UITabBar.appearance().tintColor = UIColor.orange//MARK:-2:设置全局导航栏渲染颜色UINavigationBar.appearance().tintColor = UIColor.orangereturn true}
}//MARK:-1:定义全局打印

func DLog<T> (fileName:String = #file,function:String = #function,lineNum:Int = #line, message:T) {#if DEBUGlet fileNameComponse = (fileName as NSString).lastPathComponentprint("\(fileNameComponse):\(function):\(lineNum):\("打印内容"):\(message)")#endif
}

4:子类控制器中调用

import UIKitclass HomeViewController: RHBaseTableViewController {override func viewDidLoad() {super.viewDidLoad()//MARK:-1:让iconImageView旋转
        visitorView.rotationImage()}}

import UIKitclass MessageViewController: RHBaseTableViewController {override func viewDidLoad() {super.viewDidLoad()//MARK:-1:更换图片和title,取消动画visitorView.setupVisitorView("visitordiscover_image_message", title: "支持MJExtension,没毛病,关注MJExtension,有惊喜")}}

转载于:https://www.cnblogs.com/cqb-learner/p/5922451.html

swift项目第七天:构建访客界面以及监听按钮点击相关推荐

  1. (Oracle踩坑指南)项目建立连接的各种坑 ORA-12541: TNS: 无监听程序等等

    在oracle项目建立连接中的各种坑 吐槽甲骨文一波 安装过程中遇到的问题 问题一:下载 问题二:PLSQL工具 问题三:plsql的使用 问题四:接下来到修改VisualStudio里面的web.c ...

  2. BOS项目02_02_zTree-通过ajax的获取菜单数据、监听树形菜单的点击事件、读取json文件、Ajax获取数据

    系列文章目录 文章目录 系列文章目录 前言 一.发送ajax网络请求获取菜单数据 二.监听树形菜单的点击事件 总结 前言 一.发送ajax网络请求获取菜单数据 我们现在的数是写死的,那么实际项目中我们 ...

  3. 项目对接支付宝支付,内网穿透实现监听支付宝的支付成功异步回调通知

    调试的话使用支付宝的沙箱环境来进行调试 调试的时候因为是本地调试,没有上线的域名,无法被支付宝的异步回调请求所打到,这种情况下可以使用内网穿透来进行解决 内网穿透步骤: 内网穿透的几个常用软件 1.n ...

  4. Java项目:访客管理系统(java+SpringBoot+layUi+JSP+Maven+mysql)

    源码获取:博客首页 "资源" 里下载! 项目介绍 springboot搭建的访客管理系统,针对高端基地做严格把控来访人员信息管理,用户后端可以设置多个管理员帐号,给予不同部门的管理 ...

  5. Java项目密码访客系统_springboot搭建访客管理系统的实现示例

    项目介绍 springboot搭建的访客管理系统,针对高端基地做严格把控来访人员信息管理,用户后端可以设置多个管理员帐号,给予不同部门的管理层使用,用户管理可以增加/修改内部成员的基本信息,需要到访的 ...

  6. Java项目:springboot访客管理系统

    作者主页:夜未央5788 简介:Java领域优质创作者.Java项目.学习资料.技术互助 文末获取源码 项目介绍 springboot搭建的访客管理系统,针对高端基地做严格把控来访人员信息管理,用户后 ...

  7. Swift5.x开发微博项目之访客视图第2部分

    Swift5.x开发微博项目之访客视图第2部分 本项目有点bug ,文字的高度,没有添加好宽高的约束.其他正常 代码太多,我只附着核心源码,项目源码在我的主页下面,进行代码的重构务必备份一份. imp ...

  8. Java项目访客管理系统(java+SpringBoot+layUi+JSP+Maven+mysql)

    源码获取:博客首页 "资源" 里下载! 项目介绍 springboot搭建的访客管理系统,针对高端基地做严格把控来访人员信息管理,用户后端可以设置多个管理员帐号,给予不同部门的管理 ...

  9. java网页统计访客量_Java中的访客设计模式

    java网页统计访客量 Visitor Design Pattern is one of the behavioral design pattern. 访客设计模式是行为设计​​模式之一. 访客设计模 ...

  10. gulp构建项目(三):gulp-watch监听文件改变、新增、删除

    一.gulp.watch()功能介绍 举例说明:当'./src/*.html'发生变化时,执行'html'任务,同时刷新浏览器.如下: gulp.task('watch', function(){gu ...

最新文章

  1. 满屋研选获1亿元B轮融资,华创资本领投,五岳资本、金地集团、治平资本等跟投...
  2. 你还不会创建jQuery插件 ?
  3. LeetCode 螺旋矩阵(Spiral Matrix)
  4. APPSERV下安装pear db和auth
  5. 数据结构与算法 / LRU 缓存淘汰算法
  6. opencvsharp打开相机并视频显示
  7. 官宣预热iQOO 7强悍配置:“性能铁三角”加持 给你强悍全感
  8. Vue Router 4 快速入门
  9. C# 本质论 第二章 数据类型
  10. jQuery 查找元素节点
  11. 【嵌入式系统开发08】STM32F103C8T6搭建电路实现流水灯详解
  12. Matlab中凸优化工具包CVX的安装、注册与使用
  13. android 评论发表情,安卓手机怎么在微信朋友圈评论发表情包?
  14. 先验概率 后验概率 贝叶斯法则 贝叶斯公式
  15. 秋在季节轮回里,你在思念绽放中
  16. 输入框内只能输入数字,输入其他内容不显示
  17. 有测试智商的软件不,测试智商的软件有哪些
  18. 聚合微信聊天crm调用代码
  19. 爱乐乐iLELE®益生菌新品上市由妈咪爱研究中心出品
  20. 114 西崖 柳成龍

热门文章

  1. OSChina 周三乱弹 —— 究竟是谁走漏风声
  2. 企业级监控软件使用zabbix key监控nginx status各种状态
  3. 学习笔记:Oracle的trace文件可见性
  4. 看好你的数据库连接字符串!
  5. 安卓apk的编译与反编译
  6. oracle跨库连接查询
  7. [转]Ubuntu下快速安装python
  8. 一百多道.NET面试题!
  9. 关于Platinum库的MediaRender具体C++代码实现探讨
  10. poj 2778 DNA Sequence