...闭区间
..>开区间
1、
/// 遍历
for i in 1…10 where i % 2 == 0{ //where限制条件
print(i)
}
for i in (1...10).reversed(){// .reversed方向遍历
}
2、
//外部参数, 内部参数
func song(_ total:Int){
for i in(1...total).reversed(){// total属于内部参数
print("现在有\(i)部iPhone,卖出了一部,还剩\(i-1)部啦")
}
print("全部卖光了")
}
song(10) // _属于外部参数,外部参数留空
3、 面向对象编程,简称OOP
//初始化话--实例化,从class-->object的过程
class People{ //类是全局的,不需要其他类导入,直接可以使用
let name: String
let gender: String
init(detailName:String,detailGender:String) {
name = detailName
gender = detailGender
}
}
let zhangSan = People(detailName: "张三", detailGender: "男")
4、 数组中放对象的情况非常多
// 数组的两个常用功能: 按元素大小排序 转换
let avs2 = arrays.sorted()//排序
for av in avs2 {
print(av)
}
let avengers = ["a","b","c"]
// $0代表其中一个元素
let avs3 = avengers.map {//转换
return "字母:" + $0
}
print(avs3)
5、 泛型
// T为泛型类型(广泛使用的类型),是说明 T是可比较的类型
func bigger(a: T, b: T) -> T {
if a > b {
return a
} else {
return b
}
}
var i = bigger(a: 3, b: 4)
var j = bigger(a: "a", b: "b")
print(j)
print(i)
6、 自定义类型
// struct 结构体 约等于 class-----不需要init,是一种轻量级的class
// struct 自定义类型 — (变量、函数的内部聚合)
struct Human {
var name = ""
var age = 0
var height = 0
func shuoming() {
print("\(name)的年龄是\(age),身高是\(height)")
}
}
var tonyStrk = Human(name: "Iron Man", age: 50, height: 180)
tonyStrk.shuoming()
print(tonyStrk.name)
//自定义类型 -- 外部组合 -- Swift特色
protocol flyable { // protocol协议
func takeOff(speed: Int)
}
extension Human: flyable{//扩展 Human功能
func takeOff(speed: Int) {
print("\(name)将以时速\(speed)公里起飞")
}
}
tonyStrk.takeOff(speed: 300)
7、 初始化
enum Type{
case sports
case sedan
case SUV
}
class Car {
var color = "black"
var seats = 5
// var type = Type.sports
var type:Type = .sports
/// 初始化构造器---这个class被实例化时执行的代码
init(color:String,seats:Int,type: Type) {
self.color = color
self.seats = seats
self.type = type
}
/// 遍历构造器
convenience init(){
self.init(color:"blue",seats:6, type:.sports)
}
}
8、 可选类型Optional-那些看不懂的感叹号和问号
/// optional--可选型
var desk:String?
override func viewDidLoad() {
super.viewDidLoad()
//强制解包--wrap
if(desk != nil){
print("最近的" + desk!)
}
//可选绑定---简称iflet
if let desk = desk {//有值的话,执行大括号里的内容
print("最近的\(desk)")
}
}
9、 获取用户当前位置
import UIKit
import CoreLocation
// delegate--委托
// protocol--协议
class ViewController: UIViewController,CLLocationManagerDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self // CLLocationManager的代理人是self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
locationManager.requestWhenInUseAuthorization()//请求授权获取当前位置
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters //设置位置精度, 精度越高, 耗电越大
locationManager.requestLocation()//请求用户位置---只请求一次
}
//当请求用户位置的时候立刻调用这个方法(重要方法)
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lat = locations[0].coordinate.latitude //经度
let lon = locations[0].coordinate.longitude //纬度
print(lat,lon)
}
//当位置请求失败时的回调(必须写)
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
10、 计算属性
import Foundation
class Weather {
var temp = 0
var city = ""
var condition = 0
//计算属性--compute属性
var icon:String{//需要根据别的属性来确定自己是什么的时候
switch (condition) {
case 0...300:
return "tstorm1"
default:
return "未知"
}
}
}
11、 类型转换
// 导航之前做的一些准备操作----大多数情况是传值
override func prepare(for segue:UIStoryboardSegue, sender:Any?){
if segue.identifier == "selectCity" {
// as--->向上转型upcasting或转换一般类型(类似于Int(3.2)) ---用的少
// as?--->向下转型---downcasting(可能为空的情况下使用,要用iflet.)
// as!--->向下转型---downcasting(强制转换类型,在明确的情况下使用)
let vc = segue.destination as! selectViewController
vc.currentCiyt = weather.city
}
}
12、 找到tableView所点击的cell
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//找到点击的那个cell
let cell = tableView.cellForRow(at: indexPath) as! TodoCell
//取消cell的选择状态(也就是把底色去掉)
tableView.deselectRow(at: indexPath, animated: true)
}
13、 iflet多条件判断
//判断用户有没有输入(为nil的情况) + 用户是否只输出了空格(空字符串的情况)
if let name = todoInput.text, !name.isEmpty{
}
14、 更新tableview视图
// 更新视图---view
tableView.beginUpdates()
tableView.deleteRows(at: indexPath, with: .automatic)
tableView.endUpdates()//把批量对视图的操作放在这两句话中间就能提高APP的性能
// tableView.reloadData()//在更新完数据(model)之后,这一句话就可以代替更新视图的那些代码,但是没有动画
15、 tableview cell编辑状态
/// 当用户点击editButton(编辑cell)之后会调用这个方法
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
editButtonItem.title = isEditing ? "完成" : "编辑"
}
/// 右滑删除
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
//删除数据
todos.remove(at:indexPath.row)
//2.更新tableview视图view
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
}
}
/// 更改右滑按钮title
override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "删除"
}
// 移动cell
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
//1.移动数据
let todo = todos(fromIndexPath.row)
todos.remove(at: fromIndexPath.row)
todos.insert(todo, at: to.row)
//2.更新视图
tableView.reloadData()
}
16、 定义空数组字典
//定义空数组
var todos:[Todo] = []//也可以写成 var todos = [Todo]() 或者 var todos: Array = []
//定义空字典
var dic:[String:String] = [:]//也可以写成 var dic = [String:String]
17、对象编码, userdefaluts存储对象, data解码
import Foundation
//sp1.让todo遵守codable协议, 使之可以编码
struct Todo:Codable {
var name = ""
var checked = false
}
//sp2.把数据存到本地(iPhone手机)
func saveData() {
//编码的固定格式----先创建一个编码器(JSONEncoder())----然后编码(encode)
do{
//编码后得到的data类型的数据------说白了就是一堆字符串
let data = try JSONEncoder().encode(todos)
UserDefaults.standard.set(data, forKey: "todos")
}catch{
print(error)
}
}
//sp3.从沙盒读取数据
func readData() {
//沙盒的位置--sandbox
print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
if let data = UserDefaults.standard.data(forKey: "todos") {
//解码的固定格式---先创建一个解码器( JSONdecode() )---然后解码(decode)
do{
//解码为[Todo]类型---固定写法(.self)
todos = try JSONDecoder().decode([Todo].self, from: data)
}catch{
print(error)
}
}
}
18、存储
/*
软件产品的两种形态:cs和bs
client-server----QQ,微信--所有我们安装的软件--本地存储的多
//比如微信会把聊天记录里面的数据全部存储在本机上
//本地存储的增删改查很快, 所以我们的APP比起网站运行速度要快
browser-server-----网站, 在线聊天---服务器存储用的多
//服务器需要和数据库连接, 这个连接非常耗时, 导致我们网站响应速度并没有软件cs快
本地存储数据库:
//1. userdefaults--存储轻量级的数据
//2. core data--苹果自带的-学习成本高, 代码多, 速度e没有realm快--不推荐用
//3. realm--第三方功能包
数据库:
userdefaults本质上是存储plist文件
core data和realm 本质上是一些按项目需求写好的每列是什么的表格(exal),并存储在一个文件里, 便于我们进行数据的增删改查
*/
19、使用Realm
let realm = try! Realm()
var todos: Results?//realm里面的类型---结果集的意思---类似数组的一种混合数据类型
//用Realm把数据存储到本地(iPhone手机)
func saveData(todo:Todo) {
//打印存储地址
print(Realm.Configuration.defaultConfiguration.fileURL)
do {
let realm = try Realm()
try realm.write {
realm.add(todo)
}
} catch {
print(error)
}
}
//从Realm里面读取全部数据
func readData(){
todos = realm.objects(Todo.self)//Todo.self表示传入Todo类型
}
//从Realm里面改写数据
func writeData(){
do {
try realm.write {
todos![indexPath.row].name = name
}
} catch{
print(error)
}
}
//从Realm里面删除数据
func delData(){
do {
try realm.write {
realm.delete(todos![indexPath.row])
}
} catch{
print(error)
}
}
//Realm搜索排序
func searchData() {
//1. predicate--断言--规定要怎么查询部分数据
//ascending不写的话默认是true(升序)
todos = realm.objects(Todo.self)?.filter("name CONTAINS %@",searchBar.text!).sorted(byKeyPath:"createdAT",ascending:false)
}
20、让view立刻重新布局
self.view.layer.layoutIfNeeded()
21、取消自动约束
//用代码写的控件,默认情况下xcode会帮我们推断出约束, 我们要自定义约束所以定为false
imageView.translatesAutoresizingMaskIntoConstraints = false
//设定初始的约束值---宽,高,x,y
let conWidth = imageView.widthAnchor.constraint(equalToConstant: 100)
let conHeight = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor)
let conX = imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
let conY = imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 100)
NSLayoutConstraint.activate([conWidth,conHeight,conX,conY])//激活这些约束
view.layoutIfNeeded()//立刻生效(防止掺和到animate里去)
22、参数名缩写功能
// swift自动为闭包提供参数名缩写功能,可以直接通过$0和$1等来表示闭包中的第一个第二个参数,并且对应的参数类型会根据函数类型来进行判断:
//不使用:
let numbers = [1,2,5,4,3,6,8,7]
sortNumbers = numbers.sorted(by: { (a, b) -> Bool in
return a < b
})
print("numbers -" + "\(sortNumbers)")
//使用 $0,$1
let numbers = [1,2,5,4,3,6,8,7]
var sortNumbers = numbers.sorted(by: {$0 < $1})
print("numbers -" + "\(sortNumbers)")
23、@escaping @ noescaping 逃逸闭包与非逃逸闭包
Swift 3.0之后,传递闭包到函数中的时候,系统会默认为非逃逸闭包类型(NonescapingClosures)@noescaping,逃逸闭包在闭包前要添加@escaping关键字。
从生命周期看两者区别:
非逃逸闭包的生命周期与函数相同:
1,把闭包作为参数传给函数;
2,函数中调用闭包;
3,退出函数。结束
逃逸闭包的生命周期:
1,闭包作为参数传递给函数;
2,退出函数;
3,闭包被调用,闭包生命周期结束