【Swift基础语法SnapKit自动布局库的使用】

news2024/11/25 22:37:18

文章目录

  • 前言
  • playground
  • var 和 let-元组
  • string-字典-数组
  • 闭包
  • enum
  • 类和对象
  • 属性
  • UI
    • 和OC的区别,更简洁
    • 懒加载
    • 全局文件
    • snap kit的使用
      • `top` 和 `topMargin`
  • 总结

前言

最近在学习swift和写项目,给我的感受,语言简洁和安全,在学习了基础的语法和一些必要的知识之后,因为OC的UI也用到了自动布局,所以也去探索了swift的自动布局库SnapKit,简单记录一下。

playground

开playground练习语法比较方便
请添加图片描述
有时候有些东西编译不出来记得

var 和 let-元组

import UIKit

var greeting = "Hello, playground"
var str = "hello"
str += "11"
print(str)

var a:Int = 1, b: String = "2", c:Double = 3.0
print(a, b, c)
print("b.count =", b.count, "sss")

var smile = "smile\n"
print(smile)

// 不能数字命名开头
//var 1x = 12;
//print(1x)

// 元组
var person:(name:String, age:Int) = ("iOS", 19)
print(person.name)

var car:(String, Int) = ("Benz", 10000)
var (theName, thePrice) = car
print(theName, thePrice)

// 匿名
// 在Swift语言中,常常使用符号“_”来表示匿名的概念,因此“_”也被称为匿名标识符。
var (theName1, _) = car

var obj: String? // 在普通类型后面添加符号“?”,即可将普通类型包装为Optional类型。
// 在Swift语言中,未做初始化的普通类型是不允许使用的
if obj == nil {
    print("!obj")
}

// 在使用“!”进行Optional值的拆包操作时,必须保证要#包的值不为nil,否则程序运行会出错。可以在拆包前使用if语句进行安全判断
//声明obj为String?类型
var obj2: String? = "safe"
if obj != nil {
   obj!
}

//  if-let结构中也可以同时进行多个Optional类型值的绑定
// 只有所有Optional值都不为nil,绑定才会成功,代码执行才会进入if为真的代码块中
var curObj: Int? = 9
if let temp = curObj {
    print(temp)
} else {
    curObj = 10;
}

// 当我们明确某个变量初始时为nil,并且在之后使用之前一定会被赋值时,我们可以将其声明为隐式解析的可选值,再对这个变量进行使用,就不需要进行拆包操作了
// 声明obj4为隐式解析的变量
var obj4:Int!
obj4 = 3
// 在使用时,无须再进行拆包操作,Swift会自动帮我们拆包
print(obj4 + 1)

string-字典-数组

import UIKit

var greeting = "Hello, playground"
var str = String(describing: Int.self)

var a = Int(1.9)

var my = "jackDao"
// 符串插值方法
// \()”结构可以将其他数据类型转换为字符串类型并且插入字符串数据的相应位置,也可以进行简单的运算逻辑后将结果插入原字符串中
var myself = "my name is \(my)"
print(myself)

MemoryLayout<String>.size  //16个字节 获取String类型占用的内存空间

var e:Character = "a"
var e2: [Character] = ["H", "E", "L", "L", "O"]
var e3 = String(e2)

// 使用for-in遍历可以将字符串中的字符拆解出来,这种方法有时十分好用,for-in遍历是Swift语言中一种重要的代码流程结构。String类型默认实现了迭代器相关协议,直接对其进行遍历可以取出字符串中的每一个字符元素
for charceter in e2 {
    print(charceter)
}

//判断字符串是否为空
var obj1 = ""
if obj1.isEmpty {
   print("字符串为空字符串")
}

// 在比较两个字符串的大小时,会逐个对字符的大小进行比较,直至遇到不相等的字符为止
var cp1 = "comp1", cp2 = "comp2"
    if cp1 < cp2 {
        print("cp1 is Small")
    }

var string2 = "My name is Jaki"
//全部转换为大写
string2 = string2.uppercased() //结果为"MY NAME IS JAKI"
//全部转换为小写
string2 = string2.lowercased() //结果为"my name is jaki"

//检查字符串是否有My前缀
string2.hasPrefix("My")
//检查字符串是否有jaki后缀
string2.hasSuffix("jaki")

var array: Array<Int>
var array2: [Int]

array = []
array2 = Array()
array = [1, 2, 3]
array2 = Array(arrayLiteral: 1, 3, 4)

var array3 = [String](repeating: "Hello", count: 10);
var array4 = Array(repeating: 1, count: 10)


//声明字典[param1:param2],这种结构用于表示字典类型,param1为键类型,param2为值类型
var dic1:[Int:String]
//这种方式和[:]效果一样,dic2与dic1为相同的类型
var dic2:Dictionary<Int,String>
//字典创建与赋值
dic1 = [1: "1", 2: "2", 3: "3"]
dic2 = Dictionary(dictionaryLiteral: (1, "1"),(2, "2"),(3, "3"))
//在创建字典时,也可以不显式声明字典的类型,可以通过赋初值的方式来使编译器自动推断
var dic3 = ["1": "one"]
//创建空字典
var dic4: [Int:Int] = [:]
var dic5: Dictionary<Int,Int> = Dictionary()

1==2 //等于比较,返回false
1<2  //小于比较,返回true
1>2  //大于比较,返回false
1 != 2 //不等于比较,返回true
1<=2  //小于等于比较,返回true
1>=2  //大于等于比较,返回false

for index in 1...10 {
    print(index)
}
var sum = 0
for _ in 1...10 {
    sum += 1
}

闭包

import UIKit

var greeting = "Hello, playground"
// 一个完整的函数包含函数名、参数列表、返回值和函数体,示例如下:
//标准函数,这个函数的功能是计算某个整数的平方
func myFunc(param: Int) -> Int {
   return param * param
}
// 将上面函数的功能使用闭包来实现,代码如下:
//闭包的实现方式
let myClosures = {(param1: Int) -> Int in
    return param1 * param1
}
/*闭包在语法上有这样的标准结构:{(参数列表)->返回值in闭包体}。首先闭包的最外层由大括号包围,内部由闭包关键字in来进行分割,关键字in前面为闭包结构的参数列表和返回值,其书写规则与函数一致,关键字in后面为闭包体,用于实现具体功能*/
//对函数进行调用,将返回9
myFunc(param: 3)
//对闭包进行调用,将返回9
myClosures(3)

// 闭包的返回值是可以省略的
//闭包的实现方式
let myClosures2 = {(param:Int) in
   return param * param
}
var x = myClosures2(2)
var x1 = myClosures(2)

// 自定义前缀运算符
prefix operator ++;
prefix func ++(param1: Int) -> Int {
    return param1 + 1;
}
var num = 10
++num // num++ error


enum

import UIKit

var greeting = "Hello, playground"
enum Surname {
    case 赵, 钱, 孙, 李
}
//var sur: Surname
var sur = Surname.孙

类和对象

import UIKit

var greeting = "Hello, playground"
struct Car {
    var price: Int
    var brand: String
    var pertol: Int
    
    mutating func addPertol() {
        if pertol <= 0 {
            pertol += 1
            print("add Pertol")
        }
    }
    //在默认情况下,结构体和枚举的实例方法是不允许修改实例属性的,除非将方法标记为mutating。使用mutating关键字修饰的方法可以在方法内部修改实例属性,并且在方法执行完毕后,这些修改将会保持在实例中。
    mutating func drive() {
        if pertol > 0 {
            pertol -= 1
            print("drive 10 kilometers")
        }
    }
}
var car = Car(price: 10000, brand: "Benz", pertol: 5)
print("this \(car.brand) price is \(car.price), have \(car.pertol) pertol")
for _ in 1...10 {
    if car.pertol == 0 {
        car.addPertol()
    } else {
        car.drive()
    }
}

// 在默认情况下,结构体和枚举的实例方法是不允许修改实例属性的,除非将方法标记为mutating。使用mutating关键字修饰的方法可以在方法内部修改实例属性,并且在方法执行完毕后,这些修改将会保持在实例中。
// 对引用类型进行比较操作,应使用等同运算符“===”
// Array、String、Dictionary、Set这些数据类型都是采用结构体来实现的,这点和Objective-C有着很大的区别。因此,在Swift语言中,Array、String、Dictionary、Set在数据传递时总是会被复制

属性

import UIKit

//  监听
var greeting = "Hello, playground"
class Teacher {
    var name: String {
        willSet(new) {
            print("将要设施的新名字:\(new)")
        } didSet(old) {
            print("旧名字\(old)")
        }
    }
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
var teacher = Teacher(name: "jackLi", age: 19)
teacher.name = "lyt"

// 对比类属性,Swift语言中的类方法也是通过static和class关键字来声明的,static关键字声明的类方法又被称为静态方法,其不能被子类覆写,而class关键字声明的类方法可以被类的子类覆写

import UIKit

var greeting = "Hello, playground"
// 对于有继承关系的类,类型检查有如下原则:子类实例进行父类类型的检查可以检查成功。父类实例进行子类类型的检查不可以检查成功。
var str = "Hello ios"
if str is String {
    print("greeting is String")
}



// 其实如果数组中的元素是不同类型,并且这些类型没有一个共同的基类,那么开发者可以使用AnyObject来作为引用类型的通用类型
// AnyObject是通用的引用类型
class myClassOne {
    
}
class myClassTwo {
    
}
class myClassthree {
    
}
var c1 = myClassOne()
var c2 = myClassTwo()
var c3 = myClassthree()
var classArray: Array<AnyObject> = [c1, c2, c3]
for objclass in classArray {
    print(objclass)
}


// 在Swift语言中还提供了一种更加通用的类型Any,它可以用来描述任意类型,包括值类型和引用类型
print("anyClass")
var anyClassArray: Array<Any> = [c1, c2, c3, (1, 1), "anyType"]
for objclass in anyClassArray {
    print(objclass)
}

UI

和OC的区别,更简洁

首先语言在初始的时候没有了接口文件,接口和实现是在一个文件里面的,并且我在某些界面不需要写头文件也能引用某些ViewController,除非特定的第三方库。
请添加图片描述

懒加载

  • 延续懒加载的思想
  • 语法简单 直接+lazy关键字 需要var不能let
  • 在最上面的init方法里面匿名调用方法即可
lazy var mainBackImageView: UIImageView = {
        let image1: UIImage = UIImage(named: "MainBack.png")!
        let imageView: UIImageView = UIImageView(image: image1)
        self.addSubview(imageView)
        imageView.snp .makeConstraints { make in
            make.width.equalTo(SIZE_WIDTH + 17)
            make.height.equalTo(SIZE_HEIGHT + 17)
            make.left.equalTo(-7)
            make.top.equalTo(-7)
        }
        return imageView
    }()![请添加图片描述](https://img-blog.csdnimg.cn/4242f4e15b524bb6a5c593daf5de482f.png)

请添加图片描述

全局文件

在swift的时候,本来宏定义屏幕的尺寸等,接着就发现了全局文件。

请添加图片描述
全局文件定义的内容可以在多个文件使用,随时访问。请添加图片描述

  • 例如我在全局文件定义了一些项目里面要用到的背景颜色,长宽。
  • 今天在写通知传值的时候发现可以在这里定义name,也挺方便。

snap kit的使用

和以前的使用第三方库一样,都是pod下来就能用。
请添加图片描述
和masonry感觉没有区别。

toptopMargin

在 SnapKit 中,toptopMargin 是两种不同的约束属性,用于设置视图的顶部边距。

  1. top 属性:

    • top 属性表示视图的顶部边距相对于其父视图或参考视图的顶部边距的距离。
    • 它是相对于父视图或参考视图的真实顶部边距进行约束计算的。
    • 通常在设置约束时,需要将视图与其父视图或参考视图的顶部边距之间的距离设置为特定值。
  2. topMargin 属性:

    • topMargin 属性表示视图的顶部边距相对于其父视图的布局边距的距离。
    • 它是相对于父视图的布局边距进行约束计算的。
    • top 属性相比,topMargin 属性会考虑到布局边距的影响,使得视图的位置更具适应性和灵活性。
    • 在一些布局中,特别是在使用自动布局和边距布局时,使用 topMargin 属性可以更好地处理边距的变化和调整。

总的来说,top 属性是基于视图的真实顶部边距进行约束计算的,而 topMargin 属性是基于父视图的布局边距进行约束计算的。根据你的布局需求和使用场景,选择合适的属性来设置视图的顶部边距约束。

我感觉区别不是很大,一直用的top没啥问题。

总结

swift的字典和数组,元组在写项目的时候感觉没有用到很多,字典那块的问题好像还挺多的,包括如何多层读取不报错,和OC还是有区别,研究了再来总结

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

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

相关文章

从GitHub上新拉一个项目并在mac系统下运行遇到的种种问题

如果项目已经被拉下来&#xff0c;现在我们要启动项目。 step1、需要了解该项目是什么&#xff0c;它的作用是什么&#xff0c;以及它可以解决的问题。阅读项目的介绍、文档和示例&#xff0c;确保对项目有一个基本的认识。 step2、设置开发环境&#xff1a;确保您的开发环境…

网络安全系统教程+渗透测试+学习路线(自学笔记)

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

使用Smart Install Maker为应用制作安装程序

一. 前言 Unity发布发布PC平台exe的时候&#xff0c;是生成一个Data目录和一个exe文件&#xff0c;如下&#xff1a; 而一般软件发布的时候&#xff0c;是只有一个Setup.exe这样子的安装程序&#xff0c;可以使用Smart Install Maker这个软件来制作这个Setup.exe程序。 二. S…

函数重载与缺省参数

目录 一 缺省参数 缺省参数分半缺省和全缺省。 2&#xff0c;半缺省参数 3&#xff0c;全缺省参数 4.缺省参数的注意事项 二 函数重载 2 .函数重载参数类型不同强调 三 函数名修饰规则 一 缺省参数 1.缺省参数特性(备胎) 缺省参数是指我们定义函数时有给缺省值的参数&#xf…

chatgpt赋能python:Python开发APP的SEO优化指南

Python开发APP的SEO优化指南 Python是广受欢迎的编程语言&#xff0c;它用于开发各种应用程序&#xff0c;从简单的脚本到大型网络应用程序。SEO优化对于任何应用程序的成功都非常重要&#xff0c;这篇文章将介绍一些Python开发APP的SEO实践和技巧。 为什么需要SEO优化&#…

【OpenMMLab AI实战营第二期】目标检测与MMDetection

目标检测 目标检测的基本范式 划窗 使用卷积实现密集预测 锚框 多尺度检测与FPN 单阶段&无锚框检测器选讲 RPN YOLO、SSD Focal Loss与RetinaNet FCOS YOLO系列选讲 什么是目标检测 目标检测&#xff1a;给定一张图片&#xff0c;用矩形框框出所有感兴趣物体同…

Lucene(8):Lucene底层储存结构

1 详细理解lucene存储结构 存储结构 : 索引(Index) &#xff1a; 一个目录一个索引&#xff0c;在Lucene中一个索引是放在一个文件夹中的。 段(Segment) : 一个索引(逻辑索引)由多个段组成, 多个段可以合并, 以减少读取内容时候的磁盘IO。Lucene中的数据写入会先写内存的一个…

公共场所人流数据统计如何实现?解决重识别、漏检等检测难题

https://github.com/PaddlePaddle/paddledetection当前疫情形势严峻&#xff0c;商场、火车站、地铁口等公共场所对人员流量的统计至关重要。“每天进出多少人&#xff1f;” “现在商场中人员数量有多少&#xff1f;”这些关键数据直接影响到相关防疫管控措施。因为人员基数较…

shardingsphere5.x整合springboot分库分表实战

官方文档不同版本配置变更记录&#xff1a;Spring Boot Start 配置 :: ShardingSphere pom.xml配置&#xff1a; <!--shardingsphere分库分表依赖--> <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jd…

分布式锁原理与实战一:分布式锁简介

跨JVM的线程安全问题 在单体的应用开发场景中&#xff0c;在多线程的环境下&#xff0c;涉及并发同步的时候&#xff0c;为了保证一个代码块在同一时间 只能由一个线程访问&#xff0c;我们一般可以使用 synchronized 语法和 ReetrantLock 去保证&#xff0c;这实际上是本地锁…

指针--间接寻址运算符

通常&#xff0c;只要指明要访问的变量的内存地址&#xff0c;即可直接访问变量所在的存储单元中的内容。在前面都是直接通过变量名来访问变量的内容。直接按变量名或者变量的地址存取变量的内容的访问方式&#xff0c; 称为 直接寻址&#xff08;Direct Addressing&#xff09…

STM32读取BH1750光照强度数据打印到串口

【1】BH1750是什么&#xff1f; BH1750是一种数字式环境光强度传感器&#xff08;Digital Light Sensor&#xff09;&#xff0c;也称为其他名称&#xff0c;例如GY-302传感器、BH1750FVI传感器等。它的工作原理是通过收集光线照射到传感器上的量来测量环境亮度。 使用I2C&am…

操作系统 第三章 3.2 错题整理

页面引用串长度是什么意思 合法位存在位 不存在即发生故障 区分好页表项和逻辑地址 是不同的 逻辑地址48bit 偏移量12bit 页号36bit 页表项8B 4KB/8B2^9 一个页面能存放2^9个页表项 页号9bit&#xff0c;36/94 虚拟存储器包括内存和磁盘对换区&#xff0c;工作集要频繁用到&…

深度学习:使用UNet做图像语义分割,训练自己制作的数据集,详细教程

语义分割(Semantic Segmentation)是图像处理和机器视觉一个重要分支。与分类任务不同&#xff0c;语义分割需要判断图像每个像素点的类别&#xff0c;进行精确分割。语义分割目前在自动驾驶、自动抠图、医疗影像等领域有着比较广泛的应用。我总结了使用UNet网络做图像语义分割的…

我们不一样-康耐视visionpro和apple vision pro

​ 机器视觉Halcon-不同颜色快速识别 康耐视Visionpro是美国cognex visionpro。 康耐视 VisionPro 是领先的计算机式视觉软件。它主要用于设置和部署视觉应用 - 无论是使用相机还是图像采集卡。借助 VisionPro,用户可执行各种功能,包括几何对象定位和检测、识别、测量和对准…

【Web服务应用】LVS负载均衡集群

LVS负载均衡集群 一、企业级集群含义1.1集群的含义1.2LVS一些专业术语 二、企业集群分类2.1负载均衡集群2.2高可用集群2.3高性能运算集群&#xff08;High Performance Computer Cluster&#xff09; 三、负载均衡的架构3.1负载均衡的结构 四、负载均很集群的工作模式4.1NAT模式…

JDBC连接数据库步骤(入门到进阶全)

目录 一、JDBC是什么&#xff1f; 二&#xff0c;JDBC的本质是什么&#xff1f; 为什么要用面向接口编程&#xff1f; 三、JDBC实现原理 四、使用idea开发JDBC代码配置驱动 ​编辑 五、JDBC编程六步概述 六、JDBC编程实现 1.插入实现 2.删除与更新实现 3 .类加载的方式注…

Jetson AGX Orin安装Anaconda、Cuda、Cudnn、Pytorch、Tensorrt最全教程

文章目录 一&#xff1a;Anaconda安装二&#xff1a;Cuda、Cudnn安装三&#xff1a;Pytorch安装四&#xff1a;Tensorrt安装 一&#xff1a;Anaconda安装 Jetson系列边缘开发板&#xff0c;其架构都是arm64&#xff0c;而不是传统PC的amd64&#xff0c;深度学习的环境配置方法…

chatgpt赋能python:Python对接技术在SEO中的应用

Python对接技术在SEO中的应用 Python作为一种高性能的编程语言&#xff0c;被广泛应用于各种领域&#xff0c;其中也包括了搜索引擎优化&#xff08;SEO&#xff09;领域。Python对接技术&#xff0c;也称为API对接技术&#xff0c;是指通过调用API接口来获取数据、信息或实现…

AI数字人打造之sadtalker让照片开口说话

1 sadtalker介绍 西安交通大学也开源了人工智能SadTalker模型&#xff0c;通过从音频中学习生成3D运动系数&#xff0c;使用全新的3D面部渲染器来生成头部运动&#xff0c;可以实现图片音频就能生成高质量的视频。 论文地址&#xff1a;Learning Realistic 3D Motion Coefficie…