此篇文章阐述如何Swfit实现登录功能界面,利用项目MVP结构,分层逻辑化清晰地实现需求:
功能特点:
一:项目结构如下:
二:项目区块功能分析如下:
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()
}
}
}
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)
})
}
}
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() {
}
}
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
本文主要介绍如何使用Maven插件将SpringBoot应用打包为Docker镜像,并上传到私有镜像仓库Docker Registry的过程。Docker RegistryHarbor 2.x搭建 参考《搭建Harbor 2.x仓库 - docker私仓搭建》这里不再累赘。使用Maven构建本地Docker镜像我们以项目spring-admin为例在应用的pom.xml文件中添加dockerfile-maven-plugin的依赖 <plugin> .
小伙伴们可以使用docker在线实验室进行对docker的学习,需要先登录docker官网账户才能正常使用仓库pull(以获取nginx镜像为例 docker pull nginxDockerfile先配置dockerfilevim dockerfile //首先创建编辑dockerfile文件-FROM nginx-ADD ./ /usr/share/nginx/html/...
1.获得pid方法一 :$ ps -ef $ ps -aux方法二 :pgrep:(pgrep -l 更好)一看到pgrep首先会想到什么?没错,grep!pgrep的p表明了这个命令是专门用于进程查询的grep。$ pgrep firefox1827看到了什么?没错火狐的PID,接下来又要打字了:$kill -s 9 18272
<br />硬链接和软连接的区别:<br /><br />要说明这个问题,先说明下liunx下文件和目录的本质。<br />事实上,在liunx上,目录也是文件的一种,它是储存了一张表的文件。例如有一个叫程序的文件夹,里面有两个文件1和2.在那张目录表内。它的内容是这样的<br />名称 节点<br />1 338<br />2 228<br />那么什么是节点呢?c语言我们都学过,我们简单地把节点号理解成一个数组的下标,把内存看成一个大数组,每个文件都可以看成一个数组中的一个元素,而知道了节点号,就可以找
配置 <mvc:interceptors> <mvc:interceptor> <!-- 拦截路径 --> <mvc:mapping path="/**/*.zt"/> <!-- 拦截类 --> <bean class="com.szzt.yinyiApp.interceptor.Tok
经过实践,android与php交互,已经成功搞定!一、Android 端 /** * 上传文件及参数 */ private void sendMultipart(){ File sdcache = getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; /
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测试...
参考文档:Linux(Deepin)如何安装NVIDIA显卡驱动(deepin-Linux)UOS操作系统 笔记本双显卡完美驱动NVIDIA440驱动第一次安装时,按照第一个教程,安装和配置,结束后发现效果并不理想,经过各种尝试,发现将两种方法结合以后可以起到一定的效果,并且操作相对比较简单。1. 驱动下载 首先进入NVIDIA官网下载Linux的闭源驱动:NVIDIA官网驱动下载找到对应显卡的驱动,名字和这个类似:NVIDIA-Linux-x86_64-430.50.run 。..
android——给ListView添加点击事件的三种方式
自律给我自由今天是建立计划的第一天,会按照这个维度来记录。正常饮食:正常的工作餐,正常的摄入量,无高热量食物饮料的摄入。(热量查询:薄荷健康app)睡眠步数:(数据来源于小米手环) 今日饮食 今日睡眠 今日步数 其他运动 预期 正常饮食 7-8小时 大于8000 看时间安排 实际 正常饮食 6小时10分 深睡:55分钟 4317 无 ...
import time,datetime#先获取想要取得整点的时间 然后字符串化now_time = datetime.datetime.now().strftime("%Y-%m-%d %H")+":00:00"#time strptime() 函数根据指定的格式把一个时间字符串解析为时间元组。作者:一天姿态来源:CSDN原文:https://blog.csdn.net/u01295...
另一篇文章http://www.cnblogs.com/tootwo2/p/8120053.html里面有xml的一些解释。大数据量的excel一般都是.xlsx格式的,网上使用POI读写的例子比较多,但是很少提到读写非常大数据量的excel的例子,POI官网上提到XSSF有三种读写excel,POI地址:http://poi.apache.org/spreadsheet/index.html。官...