Swift基础总结

作者: Amok校长 | 来源:发表于2019-07-02 17:27 被阅读0次
    ...闭区间
    ..>开区间
    

    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: Comparable>是说明 T是可比较的类型
    func bigger<T: Comparable>(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<Todo> = []
        //定义空字典
        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<Todo>?//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,闭包被调用,闭包生命周期结束
    

    相关文章

      网友评论

        本文标题:Swift基础总结

        本文链接:https://www.haomeiwen.com/subject/grythctx.html