Swfit-实现登录和列表网络请求MVP结构(最新2020.7)_swfit登录代码_Aftery的博客的博客-程序员秘密

技术标签: json  IOS  

此篇文章阐述如何Swfit实现登录功能界面,利用项目MVP结构,分层逻辑化清晰地实现需求:

功能特点:

  • Alamofire获取请求服务器JSON进行登录
  • 一个输入Name,一个输入Pwd,一个登录按钮,一个注册按钮
  • 输入账户密码,点击登录正确,方可跳转到Home界面
  • 点击注册按钮进行跳转到注册界面
  • UI框架用的最流行的SnapKit框架设计

一:项目结构如下:

  1. LoginView(登录的view样式)
  2. LoginPresenter(登录的接口请求)
  3. LoginModel(接口的返回参数JSON)
  4. LoginViewController(登录的控制器界面实现)

在这里插入图片描述

二:项目区块功能分析如下:

  • LoginView的界面实现,样式,代理Protocol,继承类Baseview
import UIKit

protocol  LoginViewProtocol:NSObjectProtocol{
    
    
    func onLoginClick()//登录的按钮代理
    
    func onReginClick()//注册的按钮代理
    
}

class LoginView: BaseView {
    
    
    weak var delegate:LoginViewProtocol?
    
    //用户名
    var aUserNmaeLb:UILabel?
    
    var aUserNameTf:UITextField?
    
    var aUserNameImage:UIImageView?
    
    //密码
    var aUserPsdLb:UILabel?
    
    var aUserPsdTf:UITextField?
    
    var aUserPsdImage:UIImageView?
    
    //确认按钮
    var aUserLoginBtn:UIButton?
    
    //注册按钮
    var aUserReginBtn:UIButton?
    
    override func initView() {
    
        
        let mainView = UIView()
        if let image = UIImage(named: "login_bg"){
    
             mainView.backgroundColor = UIColor(patternImage: image)
        }
        mainView.alpha = 0.95
        addSubview(mainView)
        
        mainView.snp.makeConstraints{
    (make)->Void in
            make.top.equalTo(self).offset(0)
            make.left.equalTo(self).offset(0)
            make.right.equalTo(self).offset(0)
            make.bottom.equalTo(self).offset(0)
        }
        
        let aimages = UIImageView()
        aimages.image = UIImage(named: "hy_login")
        mainView.addSubview(aimages)
        
         aimages.snp.makeConstraints{
    (make)->Void in
               make.top.equalTo(90)
               make.height.equalTo(80)
               make.width.equalTo(80)
               make.centerX.equalTo(self)
        }
        
        //用户名
        let aUserView = UIView()
        aUserView.layer.cornerRadius = 8
        aUserView.layer.borderColor = UIColor.white.cgColor
        aUserView.layer.borderWidth = 1
        mainView.addSubview(aUserView)
        
        aUserView.snp.makeConstraints{
    (make)->Void in
            make.left.equalTo(mainView).offset(10)
            make.right.equalTo(mainView).offset(-10)
            make.top.equalTo(mainView).offset(200)
            make.height.equalTo(50)
        }
        
        aUserNameImage = UIImageView()
        aUserNameImage?.image = UIImage(named: "user")
        aUserView.addSubview(aUserNameImage!)
        
        aUserNameImage?.snp.makeConstraints{
    (make)->Void in
            make.left.equalTo(aUserView).offset(10)
            make.width.equalTo(25)
            make.top.equalTo(aUserView).offset(15)
            make.height.equalTo(25)
        }
        
        aUserNameTf = UITextField()
        aUserNameTf?.placeholder = "Please input account/email."
        aUserNameTf?.text="hy"
        aUserNameTf?.textColor = UIColor.white
        aUserView.addSubview(aUserNameTf!)
       
        aUserNameTf?.snp.makeConstraints{
    (make)->Void in
           make.left.equalTo(aUserNameImage!).offset(35)
           make.width.equalTo(220)
           make.top.equalTo(aUserView).offset(0)
           make.height.equalTo(50)
        }
        
        //密码
        let aUserPsdView = UIView()
        aUserPsdView.layer.cornerRadius = 8
        aUserPsdView.layer.borderColor = UIColor.white.cgColor
        aUserPsdView.layer.borderWidth = 1
        mainView.addSubview(aUserPsdView)
        
        aUserPsdView.snp.makeConstraints{
    (make)->Void in
            make.left.equalTo(mainView).offset(10)
            make.right.equalTo(mainView).offset(-10)
            make.top.equalTo(mainView).offset(270)
            make.height.equalTo(50)
        }
        
         aUserPsdImage = UIImageView()
         aUserPsdImage?.image = UIImage(named: "pwdx")
         aUserPsdView.addSubview(aUserPsdImage!)
         
         aUserPsdImage?.snp.makeConstraints{
    (make)->Void in
             make.left.equalTo(aUserPsdView).offset(10)
             make.width.equalTo(25)
             make.top.equalTo(aUserPsdView).offset(15)
             make.height.equalTo(25)
         }
         
         aUserPsdTf = UITextField()
         aUserPsdTf?.placeholder = "Please input account/email."
         aUserPsdTf?.text="[email protected]"
         aUserPsdTf?.textColor = UIColor.white
         aUserPsdView.addSubview(aUserPsdTf!)
        
         aUserPsdTf?.snp.makeConstraints{
    (make)->Void in
            make.left.equalTo(aUserPsdImage!).offset(35)
            make.width.equalTo(220)
            make.top.equalTo(aUserPsdView).offset(0)
            make.height.equalTo(50)
         }
        
        //登录
        aUserLoginBtn = UIButton()
        aUserLoginBtn?.setTitle("登录", for: .normal)
        aUserLoginBtn?.layer.cornerRadius = 15
        aUserLoginBtn?.backgroundColor = UIColor(hexString: "#03a9f4", transparency: 1.0)
        mainView.addSubview(aUserLoginBtn!)
        
        aUserLoginBtn?.snp.makeConstraints{
    (make)->Void in
           make.top.equalTo(aUserPsdView).offset(80)
           make.left.equalTo(mainView).offset(30)
           make.right.equalTo(mainView).offset(-30)
           make.height.equalTo(50)
       }
        
        aUserLoginBtn?.addTarget(self, action: #selector(onLoginClick), for: .touchUpInside)
        
        //注册
    }
    
    @objc func onLoginClick(){
    
        if delegate != nil {
    
            delegate!.onLoginClick()
        }
    }
    
}

  • LoginPresenter接口文件的实现:
  • 主要描写了网球请求的方法,利用Alamofire框架,通过代理传递返回正确的JSON数据,控制器界面 接收model;
import UIKit
import Alamofire

protocol LoginProtocol:NSObjectProtocol {
    
    func getLoginSuccess(result:LoginModel)
    func getLoginFail(result:String)
}

struct LoginPresenter<T> where T:LoginProtocol {
    
    var view: T?
    weak var delegate:LoginProtocol?
    
    mutating func initial(_ view: T){
    
        self.view = view
    }
    
    func loginUserJson(user:String,pwd:String){
    
       let url = BASE_URL.appending("user/getUser")
               
       let params:[String:Any] = [
           "username":user,
           "password":pwd
       ]
       
       let headers: HTTPHeaders = [
           "Content-Type":"application/json"
       ]
        
        ApiUtils.shared.netWork(url: url, method: .post, params: params, headers: headers, success: {
     result in
            if let model = LoginModel.deserialize(from: result){
    
                 if model.code == "200"{
    
                    self.view?.getLoginSuccess(result: model)
                }else{
    
                    self.view?.getLoginFail(result: "Account or Password Yes!")
                }
            }else{
    
                self.view?.getLoginFail(result: "Account or Password Error!")
            }
            
        }, error: {
     error in
            self.view?.getLoginFail(result: error)
        })
    }
}
  • LoginModel主要描述的是JSON数据的model,我这json请求成功返回:如:{code = 200 ,message = “成功登录”,data:[{name:22,age:33},{name:33,age:66}]}

import UIKit
import HandyJSON

class LoginModel: HandyJSON {
    
    
    var code:String?
    var message:String?
    var data:Array<User>?
    
    required init() {
    }
}


class User: HandyJSON {
    
    
    var pushId:Bool?
    var name:String?
    var userName:String?
    
    required init() {
    }
}

  • LoginViewController控制器界面的功能实现
  • 把需要的代理都写入LoginViewController:BaseViewController,LoginProtocol,LoginViewProtocol,UITextFieldDelegate
import UIKit
import WHToast
import MBProgressHUD

class LoginViewController:BaseViewController,LoginProtocol,LoginViewProtocol,UITextFieldDelegate{
    
    
    private var loginView = LoginView()
    private var loginPresenter = LoginPresenter<LoginViewController>()
    
    private var uid:String?
    
    private var name:String?
    
    private var pwd:String?
    
    var hud:MBProgressHUD?
    
    private var cmUtil = CommonUtil()
    
    override func viewDidLoad() {
    
           super.viewDidLoad()
       }
    
    override func initView() {
    
        loginView.frame = view.bounds
        self.view.addSubview(loginView)
    }
    
    override func initData() {
    
        loginView.delegate = self
        loginView.aUserNameTf?.delegate = self
        loginView.aUserPsdTf?.delegate = self
        self.loginPresenter.initial(self)
    }
    
    
    func onLoginClick() {
    
        let name:String = loginView.aUserNameTf?.text ?? ""
        let pwd:String = loginView.aUserPsdTf?.text ?? ""
        
        if !cmUtil.isEmpty(name) && !cmUtil.isEmpty(pwd){
    
            loginPresenter.loginUserJson(user: name, pwd: pwd)
            showHud()
        }else{
    
            WHToast.showMessage("Input is not empty!", originY: 500, duration: 2, finishHandler: {
    
            })
        }
        print("登录")
    }
    
    /*
        show loading...
     */
    func showHud() {
    
        hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud?.bezelView.style = .solidColor
        hud?.bezelView.color = UIColor.black.withAlphaComponent(0.7)
        hud?.label.text = NSLocalizedString("Loading...", comment: "HUD loading title")
        hud?.contentColor = UIColor.white
        //正常情况下是10秒后消失
        hud?.hide(animated: true, afterDelay: 8.0)
    }
    
    func hidHud(){
    
        hud?.hide(animated: true, afterDelay: 0.5)
    }
    
    func onReginClick() {
    
        print("注册")
    }
    
    func getLoginSuccess(result: LoginModel) {
    
        print("成功");
        hidHud()
        let reg = HomeViewController()
        let navCtrl = UINavigationController(rootViewController: reg)
        present(navCtrl, animated: true)
    }
    
    func getLoginFail(result: String) {
    
        hidHud()
        WHToast.showMessage(result, originY: 500, duration: 2, finishHandler: {
    
        })
        print("失败");
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    
        loginView.aUserNameTf?.resignFirstResponder()
        loginView.aUserPsdTf?.resignFirstResponder()
        return true
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
        loginView.aUserNameTf?.resignFirstResponder()
        loginView.aUserPsdTf?.resignFirstResponder()
    }
}

三:Podfile配置文件调用第三方

target 'HY_SYSTEM_APP_SWFIT' do
  use_frameworks!
  pod 'Alamofire'
  pod 'SnapKit', '~> 5.0.0'
  pod 'HandyJSON', '~> 5.0.0'
  pod 'WMPageController', '~> 2.4.0'
  pod 'WHToast','~>0.0.3'
  pod 'MBProgressHUD', '~> 1.2.0'
  pod 'MJRefresh'

end

四:调取的服务器路径为自己的:
在这里插入图片描述

五:效果如图下:
在这里插入图片描述

以上此篇Swfit编写登录界面的功能需求实现到此为止,如果对你有所满意,感谢您的阅读与支持,如果有写的不好之处,欢迎指点迷津。相互进步学习… 可关注后续更多的IOS移动端文章!~Aftrey

六:Demo点击这:

Swfit-实现登录和列表网络请求MVP结构(最新2020.7)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37523448/article/details/107200703

智能推荐

【Spring boot 实战】使用Maven插件构建Docker镜像_Young丶的博客-程序员秘密

本文主要介绍如何使用Maven插件将SpringBoot应用打包为Docker镜像,并上传到私有镜像仓库Docker Registry的过程。Docker RegistryHarbor 2.x搭建 参考《搭建Harbor 2.x仓库 - docker私仓搭建》这里不再累赘。使用Maven构建本地Docker镜像我们以项目spring-admin为例在应用的pom.xml文件中添加dockerfile-maven-plugin的依赖 &lt;plugin&gt; .

docker快速入门(play-with-docker)_hayayo的博客-程序员秘密

小伙伴们可以使用docker在线实验室进行对docker的学习,需要先登录docker官网账户才能正常使用仓库pull(以获取nginx镜像为例 docker pull nginxDockerfile先配置dockerfilevim dockerfile //首先创建编辑dockerfile文件-FROM nginx-ADD ./ /usr/share/nginx/html/...

linux kill & jobs_kill jobs_cbbbc的博客-程序员秘密

1.获得pid方法一 :$ ps -ef $ ps -aux方法二 :pgrep:(pgrep -l 更好)一看到pgrep首先会想到什么?没错,grep!pgrep的p表明了这个命令是专门用于进程查询的grep。$ pgrep firefox1827看到了什么?没错火狐的PID,接下来又要打字了:$kill -s 9 18272

硬链接和软连接的区别:_软连接硬链接区别_zqx84的博客-程序员秘密

<br />硬链接和软连接的区别:<br /><br />要说明这个问题,先说明下liunx下文件和目录的本质。<br />事实上,在liunx上,目录也是文件的一种,它是储存了一张表的文件。例如有一个叫程序的文件夹,里面有两个文件1和2.在那张目录表内。它的内容是这样的<br />名称 节点<br />1 338<br />2 228<br />那么什么是节点呢?c语言我们都学过,我们简单地把节点号理解成一个数组的下标,把内存看成一个大数组,每个文件都可以看成一个数组中的一个元素,而知道了节点号,就可以找

springMVC 拦截器_ixmin的博客-程序员秘密

配置 <mvc:interceptors> <mvc:interceptor> <!-- 拦截路径 --> <mvc:mapping path="/**/*.zt"/> <!-- 拦截类 --> <bean class="com.szzt.yinyiApp.interceptor.Tok

Android OkHttp3 上传多张图片_云上人间钦自赏的博客-程序员秘密

经过实践,android与php交互,已经成功搞定!一、Android 端 /** * 上传文件及参数 */ private void sendMultipart(){ File sdcache = getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; /

随便推点

Elasticsearch之中文分词器插件es-ik的自定义热更新词库_weixin_33744141的博客-程序员秘密

1: 部署 http 服务在这使用 tomcat7 作为 web 容器, 先下载一个 tomcat7, 然后上传到某一台服务器上(192.168.80.10)。再执行以下命令tar -zxvf apache-tomcat-7.0.73.tar.gzcd apache-tomcat-7.0.73/webapp/ROOTvi hot.dic测试...

Deepin V20 卡顿解决方案初体验_deepin卡顿_澎湃小青年白羊的博客-程序员秘密

参考文档:Linux(Deepin)如何安装NVIDIA显卡驱动(deepin-Linux)UOS操作系统 笔记本双显卡完美驱动NVIDIA440驱动第一次安装时,按照第一个教程,安装和配置,结束后发现效果并不理想,经过各种尝试,发现将两种方法结合以后可以起到一定的效果,并且操作相对比较简单。1. 驱动下载 首先进入NVIDIA官网下载Linux的闭源驱动:NVIDIA官网驱动下载找到对应显卡的驱动,名字和这个类似:NVIDIA-Linux-x86_64-430.50.run 。..

三线城市java程序员的运动健身之路——20200514_高数老师的博客-程序员秘密

自律给我自由今天是建立计划的第一天,会按照这个维度来记录。正常饮食:正常的工作餐,正常的摄入量,无高热量食物饮料的摄入。(热量查询:薄荷健康app)睡眠步数:(数据来源于小米手环) 今日饮食 今日睡眠 今日步数 其他运动 预期 正常饮食 7-8小时 大于8000 看时间安排 实际 正常饮食 6小时10分 深睡:55分钟 4317 无 ...

获取整点时间_saomanchum的博客-程序员秘密

import time,datetime#先获取想要取得整点的时间 然后字符串化now_time = datetime.datetime.now().strftime("%Y-%m-%d %H")+":00:00"#time strptime() 函数根据指定的格式把一个时间字符串解析为时间元组。作者:一天姿态来源:CSDN原文:https://blog.csdn.net/u01295...

POI读写大数据量EXCEL_疯子中的扛把子的博客-程序员秘密

另一篇文章http://www.cnblogs.com/tootwo2/p/8120053.html里面有xml的一些解释。大数据量的excel一般都是.xlsx格式的,网上使用POI读写的例子比较多,但是很少提到读写非常大数据量的excel的例子,POI官网上提到XSSF有三种读写excel,POI地址:http://poi.apache.org/spreadsheet/index.html。官...

推荐文章

热门文章

相关标签