此篇文章阐述如何Swfit实现登录功能界面,利用项目MVP结构,分层逻辑化清晰地实现需求:
功能特点:
- Alamofire获取请求服务器JSON进行登录
- 一个输入Name,一个输入Pwd,一个登录按钮,一个注册按钮
- 输入账户密码,点击登录正确,方可跳转到Home界面
- 点击注册按钮进行跳转到注册界面
- UI框架用的最流行的SnapKit框架设计
一:项目结构如下:
- LoginView(登录的view样式)
- LoginPresenter(登录的接口请求)
- LoginModel(接口的返回参数JSON)
- 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="888@eiou"
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