IOS 02 SnapKit 纯代码开发

news2024/11/24 20:42:56

SnapKit是一个Swift语言写的自动布局框架,可以运行到iOS,Mac系统上;OC版本的框架是Masonry,都是出自同一个团队。

用这个框架的目的是,用起来比系统自带的API方便,他内部也是对系统API进行了封装。

为什么使用纯代码开发?

对于Storyboard,Xib可视化来说,使用直观,方便。但不方便复用布局,例如:把启动界面的布局拷贝到新界面,那有两份布局后,就不方便统一更改了。虽然可以把每个界面,封装到View,用Xib可视化布局,但我们不可能把每个控件都封装到View里面,这显然是不实际的。同时如果存在多人同时编辑Storyboard,容易导致版本控制冲突,只能按照模块拆分不同的Storyboard,不要多人编辑同一个文件。而使用纯代码开发将不会出现上述问题,代码复用性非常好。

创建项目以及改为纯代码结构

1、创建TestSnapKit项目

2、添加依赖

1)打开终端,cd 到项目根目录输入:
pod init

输入 pod init 后,会在当前目录创建Podfile文件。

2)打开Podfile文件,在该文件里面写项目依赖的SnapKit框架。

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SnapKitTest' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SnapKitTest
  #自动布局框架,原理是封装了系统提供的约束功能
  #目的是使用更方便
  #https://github.com/SnapKit/SnapKit
  pod 'SnapKit'

  target 'SnapKitTestTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'SnapKitTestUITests' do
    # Pods for testing
  end

end
 3)安装依赖

打开终端,cd 到项目根目录输入:

pod install

执行pod install 后,会下载依赖库文件到本地,关闭项目,再双击.xcworkspace文件,重新打开项目。

4)修改项目为纯代码结构

1.复制SceneDelegate文件的 var window: UIWindow? 到 AppDelegate文件,并删除SceneDelegate文件。

2. 设置默认显示界面,并删除AppDelegate文件多余的代码

3.删除info.plist文件的配置

4.删除User Script Sandboxing 的Main

运行项目,此时纯代码开发的准备工作已完成。

3、纯代码方式实现登陆界面功能 

打开ViewController文件,接下来将通过纯代码开发实现以下登录界面:

1)导入SnapKit框架
//自动布局框架
import SnapKit
2)添加控件代码实现逻辑
// MARK: - 控件
//添加一个根容器
container = UIView()
//container.backgroundColor = .red
view.addSubview(container)

//logo
let logoView = UIImageView()
logoView.image = UIImage(named: "Logo")
container.addSubview(logoView)

// MARK: - 手机号登陆按钮
container.addSubview(phoneLoginButton)

// MARK: - 登陆按钮
container.addSubview(loginButton)

// MARK: - 协议
let agrementLabelView = UILabel()
//设置标题
agrementLabelView.text = "登录即表示你同意《用户协议》和《隐私政策》"

//设置字体大小和颜色
agrementLabelView.font = UIFont.systemFont(ofSize: 12)
agrementLabelView.textColor = .gray

container.addSubview(agrementLabelView)


// MARK: - 约束
//根容器
container.snp.makeConstraints { make in
	//正数表示向下
	make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(16)
	//负数表示向上
	make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-16)
	
	make.left.equalTo(view.safeAreaLayoutGuide.snp.left).offset(16)
	make.right.equalTo(view.safeAreaLayoutGuide.snp.right).offset(-16)
}

// MARK: - logo
logoView.snp.makeConstraints { make in
	//宽高
	make.width.equalTo(100)
	make.height.equalTo(100)
	
	//距离顶部
	make.top.equalTo(100)
	
	//水平居中
	make.centerX.equalToSuperview()
	
}

// MARK: - 协议
agrementLabelView.snp.makeConstraints { make in
	//距离底部
	make.bottom.equalToSuperview()
	
	//水平居中
	make.centerX.equalToSuperview()
}

// MARK: - 登陆按钮
loginButton.snp.makeConstraints { make in
	//宽和父窗体一样
	make.width.equalToSuperview()
	make.height.equalTo(42)
	
	//底部
	make.bottom.equalTo(agrementLabelView.snp.top).offset(-30)
}

// MARK: - 手机号登陆
phoneLoginButton.snp.makeConstraints { make in
	//宽和父窗体一样
	make.width.equalToSuperview()
	make.height.equalTo(42)
	
	//底部
	make.bottom.equalTo(loginButton.snp.top).offset(-30)
}
3)懒加载创建控件
/// 手机号登录按钮
/// 这是swift中的懒加载写法
lazy var phoneLoginButton: UIButton = {
	let button = UIButton(type: .system)
	
	//设置标题
	button.setTitle("手机号登陆", for: .normal)
	
	//设置点击事件
	button.addTarget(self, action: #selector(phoneLoginClick(_:)), for: .touchUpInside)
	
	button.backgroundColor = .red
	
	//圆角大小
	button.layer.cornerRadius = 5
	
	//标题默认颜色
	button.setTitleColor(.white,for: .normal)
	
	//按下文本颜色
	button.setTitleColor(.gray,for: .highlighted)
	
	return button
}()
4)完整ViewController文件代码:
//
//  ViewController.swift
//  SnapKitTest
//
//  Created by jin on 2024/8/12.
//

import UIKit

//自动布局框架
import SnapKit

class ViewController: UIViewController {
    
    var container: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        // MARK: - 控件
        //添加一个根容器
        container = UIView()
        //container.backgroundColor = .red
        view.addSubview(container)
        
        //logo
        let logoView = UIImageView()
        logoView.image = UIImage(named: "Logo")
        container.addSubview(logoView)
        
        // MARK: - 手机号登陆按钮
        container.addSubview(phoneLoginButton)
        
        // MARK: - 登陆按钮
        container.addSubview(loginButton)
        
        // MARK: - 协议
        let agrementLabelView = UILabel()
        //设置标题
        agrementLabelView.text = "登录即表示你同意《用户协议》和《隐私政策》"
        
        //设置字体大小和颜色
        agrementLabelView.font = UIFont.systemFont(ofSize: 12)
        agrementLabelView.textColor = .gray
        
        container.addSubview(agrementLabelView)
        
        
        // MARK: - 约束
        //根容器
        container.snp.makeConstraints { make in
            //正数表示向下
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(16)
            //负数表示向上
            make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-16)
            
            make.left.equalTo(view.safeAreaLayoutGuide.snp.left).offset(16)
            make.right.equalTo(view.safeAreaLayoutGuide.snp.right).offset(-16)
        }
        
        // MARK: - logo
        logoView.snp.makeConstraints { make in
            //宽高
            make.width.equalTo(100)
            make.height.equalTo(100)
            
            //距离顶部
            make.top.equalTo(100)
            
            //水平居中
            make.centerX.equalToSuperview()
            
        }
        
        // MARK: - 协议
        agrementLabelView.snp.makeConstraints { make in
            //距离底部
            make.bottom.equalToSuperview()
            
            //水平居中
            make.centerX.equalToSuperview()
        }
        
        // MARK: - 登陆按钮
        loginButton.snp.makeConstraints { make in
            //宽和父窗体一样
            make.width.equalToSuperview()
            make.height.equalTo(42)
            
            //底部
            make.bottom.equalTo(agrementLabelView.snp.top).offset(-30)
        }
        
        // MARK: - 手机号登陆
        phoneLoginButton.snp.makeConstraints { make in
            //宽和父窗体一样
            make.width.equalToSuperview()
            make.height.equalTo(42)
            
            //底部
            make.bottom.equalTo(loginButton.snp.top).offset(-30)
        }
        
    }
    
    @objc func phoneLoginClick(_ s:UIButton) {
        print("点击按钮")
    }

    /// 手机号登录按钮
    /// 这是swift中的懒加载写法
    lazy var phoneLoginButton: UIButton = {
        let button = UIButton(type: .system)
        
        //设置标题
        button.setTitle("手机号登陆", for: .normal)
        
        //设置点击事件
        button.addTarget(self, action: #selector(phoneLoginClick(_:)), for: .touchUpInside)
        
        button.backgroundColor = .red
        
        //圆角大小
        button.layer.cornerRadius = 5
        
        //标题默认颜色
        button.setTitleColor(.white,for: .normal)
        
        //按下文本颜色
        button.setTitleColor(.gray,for: .highlighted)
        
        return button
    }()
    
    
    ///用户名和密码登录
    lazy var loginButton: UIButton = {
        let button = UIButton(type: .system)
        
        //设置标题
        button.setTitle("用户名和密码登录", for: .normal)
        
        //设置点击事件
        button.addTarget(self, action: #selector(phoneLoginClick(_:)), for: .touchUpInside)
        
        button.backgroundColor = .clear
        
        //圆角大小
        button.layer.cornerRadius = 21
        
        button.layer.borderWidth = 1
        button.layer.borderColor = UIColor.red.cgColor
        
        //标题默认颜色
        button.setTitleColor(.red,for: .normal)
        
        //按下文本颜色
        button.setTitleColor(.gray,for: .highlighted)
        
        return button
    }()
}

至此完成了一个通过纯代码开发实现登录界面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033371.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

房产中介小程序

本文来自:ThinkPHPFastAdmin房产中介小程序 - 源码1688 应用介绍 产中介小程序是一款基于ThinkPHPFastAdmin开发的原生微信小程序,为房地产中介提供房源管理、发布、报备客户、跟踪客户以及营销推广获客等服务的系统。 前端演示: 后台演示&am…

HarmonyOS应用开发者基础认证(三)

1、针对包含文本元素的组件,例如Text、Button、TextInput等,可以使用下列哪些属性:(全选) 答案: fontColor fontFamily fontSize fontWeight fontStyle 分析: 2、关于Tabs组件和TabContent组件&…

【高效笔记与整理的艺术】

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

通过jmeter对websocket后台做压测

后台使用java程序,通过springboot集成的stomp协议暴露websocket接口,所以下文测试过程会有特定的stomp报文,无需在意,关注流程即可 本次测试使用jmeter模拟大量用户接收群消息的场景,可覆盖连接数以及消息并发的压测 一…

CentOS7.6 RabbitMQ消息队列集群部署——实施方案

1、前期环境准备(每个主机都配置) 1.准备三台主机 IP地址主机名内存大小192.168.200.10 rabbitmq1 2G192.168.200.11rabbitmq22G192.168.200.55rabbitmq32G 2. 设置主机名 hostnamectl set-hostname 主机名suexit Ctrlr 3. 设置IP地址然后重启网卡 …

深度学习与图像修复:ADetailer插件在Stable Diffusion中的应用

文章目录 引言ADetailer插件介绍插件安装常用模型控制提示词参数配置参数详解 实践建议 示例插件的对比:1. ADetailer插件2. Photoshop插件(如Nik Collection)3. GIMP插件(如GMIC)4. Affinity Photo插件 结语 引言 无…

【物联网】(蓝牙篇)微信小程序ios如何自动打开蓝牙

微信小程序打开蓝牙的便捷之道——微信小程序ios如何自动打开蓝牙 随着智能手机蓝牙技术和物联网产品的普及,很多人在使用微信小程序时,都希望能够更便捷地打开蓝牙功能。 在iOS系统上,由于其封闭性和权限控制严格,使得自动打开蓝…

OpenGL ES->GLSurfaceView进行点、线段、三角形等基本图元的绘制

GLSurfaceView代码见OpenGL ES->顶点着色器和片段着色器代码,只修改顶点数组,片段着色器的颜色,和绘制方式进行不同图元绘制 绘制点 GL_POINTS方式 // 顶点数据 val vertices floatArrayOf(0.8f, -0.8f, 0.0f,-0.8f, -0.8f, 0…

Python大数据分析——SVM模型(支持向量机)

Python大数据分析——SVM模型(支持向量机) 认知模型介绍距离计算模型思想目标函数函数与几何间隔 线性可分SVM模型目标函数函数代码 非线性可分SVM模型目标函数函数代码 示例手写体字母识别森林火灾面积预测 认知模型 介绍 超平面的理解:在…

Stable Diffusion绘画 | 进阶语法

控制提示词生效时间 使用格式1:[提示词:0-1数值] 举例:forest,lots of trees and stones,[flowers:0.7] 其中 [flowers:0.7] 表示整体画面采样值达到70%的进程以后,才开始计算花的采样。 因此,花的数量仅仅只跑了末段的30%&am…

LeetCode之回溯

1.全排列 1.1 题目 1.2 题解 LeetCode 力扣官方题解 1.3 代码 class Solution {public List<List<Integer>> permute(int[] nums) {// 创建一个空的列表 res&#xff0c;用于存储所有的排列结果List<List<Integer>> res new ArrayList<>();/…

C++入门基础:数据类型与条件判断语句

数据类型 基础数据类型 整型&#xff08;Integral Types&#xff09; int&#xff1a;基本的整型&#xff0c;大小依赖于编译器和平台&#xff0c;通常是32位或64位。 short&#xff1a;短整型&#xff0c;通常是16位。 long&#xff1a;长整型&#xff0c;大小依赖于编译…

本地部署Code Llama大模型结合Text generation Web UI远程运行LLM

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

pdf拆分成一页一页,怎么操作?pdf拆分的好用方法

pdf拆分成一页一页&#xff0c;怎么操作&#xff1f;PDF文件的拆分通常涉及到以下几个常见场景和需求&#xff1a;首先&#xff0c;PDF文件可能包含大量的页面&#xff0c;例如数百页的电子书或详尽的技术手册。在某些情况下&#xff0c;用户可能只需要处理其中的几页或者想要单…

揭秘!亚马逊与速卖通自养号测评:必备资源与技术要点

面对测评服务商的种种承诺&#xff0c;其真实性往往难以验证&#xff0c;而在像Facebook这样的社交平台上自行寻找测评资源&#xff0c;也显得相当困难和不切实际。随着产品即将上架&#xff0c;寻找一个可靠的测评服务似乎并不那么容易。因此&#xff0c;对于亚马逊等跨境平台…

运动耳机哪个品牌好用?五款质量一流品牌推荐!

运动耳机无疑是运动爱好者的绝佳伴侣&#xff0c;让每一次挥汗如雨的瞬间都伴随着无与伦比的音乐盛宴与舒适的佩戴感受。特别是对于跑步爱好者而言&#xff0c;一款优秀的运动耳机更是不可或缺的装备。然而&#xff0c;市场上的运动耳机种类繁多&#xff0c;质量也千差万别&…

Mirror学习笔记(五)概念指南

文章目录 一、Authority(权限)二、IDs(身份编号)三、Attributes(属性)四、Time Synchronization(同步时间)五、Data types(数据类型)六、Serialization(序列化)七、Synchronization(同步)八、Communications(通讯)九、GameObject(游戏对象) 顶层脚本API: Mirror是一个高级网络库…

Qt信号与槽-思维导图-学习笔记

Qt 信号与槽 Qt 信号与槽机制 基本概念 信号与槽机制&#xff1a;Qt 编程的基础与创新&#xff0c;使得处理界面组件交互操作更加直观和简单 信号&#xff08;Signal&#xff09;&#xff1a;在特定情况下被发射的事件&#xff0c;如按钮点击的 clicked() 信号、组合框项变化…

服务器数据恢复—服务器raid常见故障产生原因数据恢复方案

磁盘阵列&#xff08;raid&#xff09;是一种将多块物理硬盘整合成一个虚拟存储的技术。raid模块相当于一个存储管理中间层&#xff0c;上层接收并执行操作系统及文件系统的数据读写指令&#xff0c;下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬盘&#xff0…

超算互联网-Stable Diffusion 2.1文生图教程

一、名词简介 1. 超算互联网 超算互联网是一种基于云计算的高性能计算平台&#xff0c;用户可以通过互联网接入超级计算资源。它集成了大量的计算节点&#xff0c;提供强大的计算能力&#xff0c;适用于科学计算、深度学习、人工智能等领域。用户可以利用超算互联网平台运行复…