• IOS swift3.0 下闭包语法整理 一、闭包的概念 有oc基础的都知道,闭包其实是oc里面的block,语法格式不一样,但作用是一样的。主要是用于callBack(异步回调)或者两个类之间的通信。它的本质一个函数,一个可...

    http://www.jb51.net/article/97240.htm

    IOS swift3.0 下闭包语法整理

    一、闭包的概念

    有oc基础的都知道,闭包其实是oc里面的block,语法格式不一样,但作用是一样的。主要是用于callBack(异步回调)或者两个类之间的通信。它的本质一个函数,一个可执行的代码块,只是这个函数是没有名字的,也就是匿名函数。你也可以把他看作如 int、float一样,是一种数据类型,一种可以作为参数传递的数据类型。

    二、基本语法

    1、闭包的声明

     //定义一个求和闭包
        //闭包类型:(Int,Int)->(Int)
        let add:(Int,Int)->(Int) = {
          (a,b) in
          return a + b;
        }
       //执行闭包,相当于调用函数 
       let result = add(1100, 200);
        //打印闭包返回值
        print("result=\(result)");
    

    闭包类型是由参数返回值决定,如上述add闭包类型为(Int,Int)->(Int),箭头前面括号是参数类型,多个参数逗号隔开,箭头后面括号返回值类型。

    分析下上面代码,“=”左边的“ let add:(Int,Int)->(Int) ”意思是声明一个add常量,add是一个闭包类型,并且这个闭包的类型是:(Int,Int)->(Int)。

    “=”右边是一个代码块,即闭包的具体实现,相当于给左边add常量赋值。代码块的语法格式:

    {
        (参数1,参数2) in
        //code
     }
    

    参数和需执行的代码(code)用 关键字“in”隔开,如果闭包没有参数, “ () in”可以直接省略:

    {
      //code
     }
    

    你也可以用关键字“typealias”先声明一个闭包的数据类型

    import UIKit
    
    //声明一个闭包类型 AddBlock
    typealias AddBlock = (Int,Int)->(Int);
    
    class ViewController: UIViewController {
    
      override func viewDidLoad() {
        super.viewDidLoad()
        let add:AddBlock = {
          (a,b) in
          return a + b;
        }
    
       let result = add(1100, 200);
        print("result=\(result)");
     }
    }
    
    

    3、闭包的用法

    1、两个类之间的通信

    ios中类之间的通信方式有多种,常用的有:协议代理、通知,以及本章要讲的闭包。因为协议代理用起来比较麻烦,又是声明协议方法、又要设置代理的,代码步骤太多,我一般不用;通知一般用于两个完全没有关联的类通信,可以一对多,但解耦和的太厉害,我一般是特定的场合用。所以针对有关联的两个类之间的通信,我一般是用闭包或block的,这样比较简洁迅速。

    示例程序:监听控制器上一个自定义view按钮的点击


    界面效果

    CustomView类中代码

    class CustomView: UIView {
    
      //声明一个属性btnClickBlock,type为闭包可选类型
      //闭包类型:()->() ,无参数,无返回值
      var btnClickBlock:(()->())?;
    
      //重写 init(frame: CGRect)构造函数
      override init(frame: CGRect) {
        super.init(frame:frame);
        //创建按钮
        let btn = UIButton(frame: CGRect(x: 15, y: 15, width: 80, height: 32));
        btn.setTitle("按钮", for: .normal);
        btn.backgroundColor = UIColor.blue;
        //绑定事件
        btn.addTarget(self, action: #selector(CustomView.btnClick), for: .touchDown);
        //添加
        addSubview(btn);
    
      }
      //按钮点击事件函数
      func btnClick(){
    
        if self.btnClickBlock != nil {
          //点击按钮执行闭包
          //注意:属性btnClickBlock是可选类型,需要先解包
          self.btnClickBlock!();
        }
      }
    
      required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
      }
    
    }
    
    

    Controller类中代码:

    class ViewController: UIViewController {
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        //创建CustomView对象
        let cutomeView = CustomView(frame: CGRect(x: 50, y: 50, width: 200, height: 200));
        //给cutomeView的btnClickBlock闭包属性赋值
        cutomeView.btnClickBlock = {
          // () in 无参数可以省略
          //当按钮被点击时会执行此代码块
          print("按钮被点击");
        }
        cutomeView.backgroundColor = UIColor.yellow;
        //添加到控制器view上
        self.view.addSubview(cutomeView);
    
      }
    }
    
    

    2、异步回调(callBack)

    以发送一个简单的网络请求为例:

    /// 定义一个网络请求函数
      ///
      /// - parameter urlString: 请求接口  String
      /// - parameter succeed:  成功的回调 可选闭包
      /// - parameter failure:  失败的回调 可选闭包
      func requestData(urlString:String,succeed: ((Any?)->(Void))?,failure:((Any?)->(Void))?){
    
        let request = URLRequest(url: URL(string: urlString)!);
    
        //发送网络请求
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue()) { (_, data, error) in
          if error == nil {
            //请求成功,执行成功的回调,并把数据传递出去
            succeed?(data);
          }else{
             //请求失败,执行失败的回调,并把错误传递出去
            failure?(error);
          }
        }
      }
    
    
    // 调用函数requestData函数
        requestData(urlString: "http://www.baidu.com", succeed: { (data) -> (Void) in
    
          //成功的回调
          guard let result = data as? Data else{
            return;
          }
    
          let srt = NSString(data: result, encoding: String.Encoding.utf8.rawValue);
    
          print(srt!)
    
    
          }) { (error) -> (Void) in
            //失败的的回调
            print(error);
        }
    
    

    四、闭包的一些特殊语法

    1、尾随闭包

    当闭包作为函数的最后一个参数时,可以省略前面的括号。尾随闭包没什么特殊的作用,纯粹是一种语法上的简洁,增加易读性。

    例:定义一个函数:

    //第二个参数:闭包 (String)->(Void)
    func post(url:String,succesce:(String)->Void) {
    
        print("发送请求");
    
        succesce("请求完成");
      }
    
    

    执行函数,正常写法:

     //正常写法,第二个参数,传递一个闭包
       post("http", succesce: {
          //闭包传递的参数
          (json) in
          //执行的代码
           print(json);
    
        });
    
    

    执行函数,尾随闭包写法:

    //尾随闭包,当闭包作为函数的最后一个参数时,可以省略前面的括号
     HttpTool.post("http") { (json) in
          print(json);
        };
    

    2、逃逸闭包

    看起来很“吊炸天”的一个名字,其实很简单。当闭包作为一个参数传递到函数时,我们知道它一般是用于函数内部的异步回调,闭包是等异步任务完成以后才调用,而函数是会很快执行完毕并返回的,所以闭包它需要逃逸,以便稍后的回调。

    逃逸闭包一般用于异步函数的回调,比如网络请求成功的回调和失败的回调。语法:在函数的闭包行参前加关键字“@escaping”。

    或许细心的人已经发现我上面的示例网络请求为什么没有出现关键字“@escaping”,你可以拉回去看下成功回调或失败的回调,类型是“((Any?)->(Void))?”,后面带了个“?”,这是闭包可选类型,并不是闭包类型,所以无需关键字“@escaping”。

    假设成功和失败的回调要弄成闭包类型,而你又要异步使用的话,那就要在形参前面加关键字,如下:

     /// 定义一个网络请求函数
      ///
      /// - parameter urlString: 请求接口  String
      /// - parameter succeed: 成功的回调 闭包 因需要异步使用,前面加关键字@escaping修饰,指明其为逃逸闭包
      /// - parameter failure: 失败的回调 闭包 因需要异步使用,前面加关键字@escaping修饰,指明其为逃逸闭包
      func requestData(urlString:String,succeed: @escaping (Any?)->(Void),failure:@escaping (Any?)->(Void)){
    
        let request = URLRequest(url: URL(string: urlString)!);
    
        //发送网络请求
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue()) { (_, data, error) in
          if error == nil {
            //请求成功,执行成功的回调,并把数据传递出去
            succeed(data);
          }else{
             //请求失败,执行失败的回调,并把错误传递出去
            failure(error);
          }
        }
      }
    
    

    假设成功和失败的回调要弄成闭包类型,而你又要异步使用的话,但你又不想在形参前面加关键字,那对不起,我也没有办法,编译直接报错!


    展开全文
  • iOS Swift字符串截取

    2017-02-22 11:17:25
    Swift的字符串截取由三种方式下面我们一次介绍 方式一 根据index进行简单截取 // 声明一个字符串 Swift中字符串的类型是String类型 var strTest = "01224312" // 得到第一个字符的index var index = strTest....

    Swift的字符串截取由三种方式下面我们一次介绍
    方式一 根据index进行简单截取

    // 声明一个字符串 Swift中字符串的类型是String类型
    var strTest = "01224312"
    // 得到第一个字符的index
    var index = strTest.dstartIndex
    // 得到最后一个字符的index
    var index_end = strTest.endIndex
    // 前一个位置predecessor
    var index_p1 = index_end.predecessor()
    // 后一个位置successor()
    var index_s1 = index.successor().predecessor()
    // 根据index进行截取 前一个和后一个可以套用 适合小范围的截取
    var subString = strTest.substringFromIndex(index_s1)
    

    方式二:转成NSString类型后进行截取

    var strTest = "01224312"
    // 将String转成NSString类型
    // 使用as 关键字指定目标类型
    var nsstr1 = (strTest as NSString).substringFromIndex(5)
    // 这样就可以灵活的进行截取

    方式三:使用advancedBy()进行截取

    // 声明一个字符串
    var strTest2 = "01234567"
    // 通过advancedBy()方法得到位置进行截取
    let index_str2 = strTest2.startIndex.advancedBy(3)
    var subStrTest2 = strTest2.substringToIndex(index_str2)
    // 也可以调用下面的方法截取中间截取
    strTest.substringWithRange(<#T##aRange: Range<Index>##Range<Index>#>)
    展开全文
  • 本文总结 asas!、as? 这三种类型转换操作符的异同,以及各自的使用场景。 as 有保证的转换,从派生类转换为基类的向上转型(upcasts) 使用场合: 从派生类转换为基类,向上转型(upcasts) class Animal {}...
    本文总结 as、as!、as? 这三种类型转换操作符的异同,以及各自的使用场景。

    as

    有保证的转换,从派生类转换为基类的向上转型(upcasts)
    使用场合:

    • 从派生类转换为基类,向上转型(upcasts)
    class Animal {}
    class Cat: Animal {}
    let cat = Cat()
    let animal = cat as Animal
    • 消除二义性,数值类型转换
    let num1 = 42 as CGFloat
    let num2 = 42 as Int
    let num3 = 42.5 as Int
    let num4 = (42 / 2) as Double
    • switch 语句中进行模式匹配

    如果不知道一个对象是什么类型,你可以通过switch语法检测它的类型,并且尝试在不同的情况下使用对应的类型进行相应的处理。

    switch animal {
        case let cat as Cat:
        print("如果是Cat类型对象,则做相应处理")
        case let dog as Dog:
        print("如果是Dog类型对象,则做相应处理")
        default: break
    }

    as!

    强制类型转换,向下转型(Downcasting)时使用,子类(派生类)向父类转换,如果转换失败会报 runtime 运行错误。

    官方解释说这是一个不被保证的转换,可能会因为强转的失败而会导致崩溃。同时 !是一个陷阱的标志,就像⚠️一样,用起来存在一定危险性。
    示例代码:

    class Animal {}
    class Cat: Animal {}
    let animal :Animal  = Cat()
    let cat = animal as! Cat

    as?

    [as?] 和 [as!] 操作符的转换规则完全一样。但 [as?] 如果转换不成功的时候便会返回一个 nil 对象。成功的话返回可选类型值(optional)。由于 [as?] 在转换失败的时候也不会出现错误,所以对于如果能确保100%会成功的转换则可使用 [as!] ,否则使用 [as?] 。
    示例代码:

    let animal:Animal = Cat()
    if let cat = animal as? Cat{
        print("cat is not nil")
        } else {
        print("cat is nil")
    }

    原文地址:https://www.jianshu.com/p/ebe29d97b5e9

    展开全文
  • swift项目常用的扩展 1.UIColor的扩展 extension UIColor {  open static func rgbColor(_ r:CGFloat, _ g:CGFloat, _ b:CGFloat, _ alpha:CGFloat = 1.0) -&gt; UIColor{  let color:UIColor = UIColor(red...

    swift项目常用的扩展

    1.UIColor的扩展

    extension UIColor {
        open static func rgbColor(_ r:CGFloat, _ g:CGFloat, _ b:CGFloat, _ alpha:CGFloat = 1.0) -> UIColor{
            let color:UIColor = UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: alpha)
            return color
        }    
        open static func randomColor() -> UIColor {
            return UIColor(red: randomColorCount(0, 256)/255.0, green: randomColorCount(0, 256)/255.0, blue: randomColorCount(0, 256)/255.0, alpha: 1.0)
        }
        private static func randomColorCount(_ startIndex:Int, _ endIndex:Int) -> CGFloat{
            let range = Range<Int>(startIndex...endIndex)
            let count = UInt32(range.upperBound - range.lowerBound)
            let v = Int(arc4random_uniform(count))+range.lowerBound
            return CGFloat(v)
        }
        open static func colorWithHexString(_ stringToConvert: String) -> UIColor {
            let scanner = Scanner(string: stringToConvert)
            var hexNum: UInt32 = 0
            guard scanner.scanHexInt32(&hexNum) else {
                return UIColor.red
            }
            return UIColor.colorWithRGBHex(hexNum)
        }
        open static func colorWithRGBHex(_ hex: UInt32) -> UIColor {
            let r = (hex >> 16) & 0xFF
            let g = (hex >> 8) & 0xFF
            let b = (hex) & 0xFF
            return UIColor(red: CGFloat(r) / CGFloat(255.0), green: CGFloat(g) / CGFloat(255.0), blue: CGFloat(b) / CGFloat(255.0), alpha: 1.0)
        }
    }

    2.UILaber固定宽度或者固定高度算得高度或者宽度的扩展

    extension UILabel{
         //MARK:固定宽度或者高度,求得UILabel的所需要的高度或者宽度,返回结果 +5 个单位使其不拥挤
        func sizeToFitWithWidth(width:Double)->CGFloat{
           let size = CGSize.init(width: width, height: 10000)
            let targetSize:CGRect = self.text!.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font:self.font], context: nil)

          return targetSize.height+5
        
        }
        func sizeToFitHeight(height:Double) -> CGFloat {
            let size = CGSize.init(width: 10000, height: height)
            let targetSize:CGRect = self.text!.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font:self.font], context: nil)
            return targetSize.width+5
        }
    }

    3.常用的全局变量
    let defaults = UserDefaults.standard
    let kStatusBarH = UIApplication.shared.statusBarFrame.size.height               //状态栏高度
    let kNavigationBarH = UINavigationController.init().navigationBar.frame.height  //导航栏Bar高度
    let kNavigationH = (kStatusBarH + kNavigationBarH)                              //导航高度
    let kTabBarH = UITabBarController.init().tabBar.frame.height                    //tabbar高度
    let kScreenWidth = UIScreen.main.bounds.size.width
    let kScreenHeight = UIScreen.main.bounds.size.height                             //屏幕高
    // 判断系统版本
    func kIS_IOS7() ->Bool { return (UIDevice.current.systemVersion as NSString).doubleValue >= 7.0 }
    func kIS_IOS8() -> Bool { return (UIDevice.current.systemVersion as NSString).doubleValue >= 8.0 }

    展开全文
  • 上一篇我们完成了第一个用swift写的ios小程序,今天我们拓展一下那个程序,使用UICollectionView。 UICollectionView类似android中的gridview可以实现九宫格的效果。 首先我们还是打开我们的故事版main....

    上一篇我们完成了第一个用swift写的ios小程序,今天我们拓展一下那个程序,使用UICollectionView。

    UICollectionView类似android中的gridview可以实现九宫格的效果。

    首先我们还是打开我们的故事版main.storyboard拖拽一个Collection View


    默认是带一个Collection View Cell ,相当于我们的九宫格里面的子view,我们可以往cell里面拖拽控件,这些cell需要有一个标识符"Indentifier",我们这里的标识符就叫cell


    同时我们需要把控制器和视图链接


    • 提示框里面显示"Outlets"里面有fataSource和delegate
    • 数据源和委托属性与当前的视图控制器关联
    • 程序运行时,会在相关控制器中寻找相关方法
         我们修改一下背景色,往cell里面放入一个label控件

    我们新建一个控制器继承UICollectionViewCell
    import UIKit
    
    class CountCollectionViewCell: UICollectionViewCell {
       
        @IBOutlet weak var label: UILabel!
        var mUtil = Util()
        
        override init(frame:CGRect) {
            super.init(frame: frame)
        }
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
        
        func setViewLabel(index:NSIndexPath){
            self.label.text=mUtil.getCharacter(index)
        }
       
    }

    required修饰符可以看看这篇博客http://blog.csdn.net/yongyinmg/article/details/39673345

    同时我们也可以看到swift定义函数的方式为 func 方法名 (方法参数) -> 返回值
    接下来我们看看我们的ViewControll具体做了什么
    import UIKit
    
    class ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate {
    
        @IBOutlet weak var textField: UITextField!
      
        @IBOutlet weak var mCollectionView: UICollectionView!
        var cell:CountCollectionViewCell? = nil
        var mUtil = Util()
        
        //当控制器的视图类加载完成时调用
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        //当系统触发内存警告时调用
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        //cell个数
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
            return 15;
        }
        
        //相当于android中的getview
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{
             cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as CountCollectionViewCell
            cell!.setViewLabel(indexPath)
            return cell!
        }
    
        //具体点击的哪个cell
        func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
                textField.text = mUtil.getCharacter(indexPath)
            
        }
        
       
    }

    最重要的就是相当于android中的getview方法,我们把我们的cell回调给上层得以在界面中显示出来,接下来看看效果






    展开全文
  • 新建Swift文件和xib文件 Swift 文件 xib文件 (名字与Swift文件相同) Swift文件中的代码import UIKit class LXFView: UIView { // MARK:- 创建视图 class func newInstance() -> LXFView? { let nibView = ...
  • 三个文件:ViewController.swift DemoView.swift DemoView.xib 首先,可以专心将DemoView.xib画出来,别忘记DemoView.xib中UIView的一处设置 然后,写DemoView.swift文件,代码如下: clas
  • IOS swift版 sqlite3详解

    2017-03-01 16:11:01
    IOS中的SQLite3的封装与详细应用SQLite是一个开源的嵌入式关系数据库,特点是易使用、高效、安全可靠、可移植性强。IOS中的本地持久化存储NSUserDefault:一般用于存储小规模数据、业务逻辑弱的数据。keychain: 苹果...
  • var testString = "This is a test string" var nsdata = testString.data(using: String.Encoding.utf8)//NSData 类型 var strdata = String(data: nsdata !, encoding: String.Encoding.utf8) as String!//String
  • 今天我们用swift创建一个自定义的alertView(弹框),但是我们如果用代码来实现会发现坐标适配很麻烦所以,我们今天主要使用Xib。 1、首先我们要先创建一个继承UIView的一个自定义View的类,如下图 2、我们要...
  • iosswift教程

    2019-06-13 20:38:23
    学习swift地址 https://docs.swift.org/swift-book/GuidedTour/GuidedTour.html 在wwdc2019上看到了苹果公司关于swiftui的介绍,感觉这就是未来。 Swift编程语言简介 Swift命令行操作 Swift defines away large ...
  • IOS swift 网络请求数据

    2018-08-24 17:53:38
    // 首先网络请求首先得去inof.plist文件中添加Allow Arbitrary Loads in Web Content允许网络请求 // 然后创建一个继承与uiviewcontroller的类 和 继承与nsobject的model类 // 接下来就是代码了 ...
  • 目前正在学习中,只知道三种界面跳转方式 1、通过Main.storyboard 用鼠标拖拽控件到需要跳转的页面,选择 Present Modally 实现界面跳转 2、跳转到Main.storyboard 创建了 View Controller 关联代码ViewController...
  • iOS Swift RSA

    2018-01-03 10:52:35
    Swift3之后: 参考github链接: https://github.com/TakeScoop/SwiftyRSA Swift3之前: copy 下面三个文件代码到项目中,然后在桥文件 ...-Bridging-Header.h 中加上  #import "NSData+SHA.h" 最后在需要...
  • iOS开发系列--Swift进阶

    2018-08-07 22:45:34
    概述 上一篇文章《iOS开发系列--Swift语言》中对Swift的语法特点以及它和C、ObjC等其他语言的用法区别进行了介绍。当然,这只是Swift的入门基础,但是仅仅了解这些对于使用Swift进行
  • 正在学习swift的Core Data,做个笔记,顺便分享源码 这个实例是一个很简单的Table,通过右上角的Add按钮可以添加新的用户名。数据存储在CoreData中,这样,才不会丢失。 通过这个例子可以学会: 使用Xcode的model...
  • 1.通常都是使用Reachability来检查网络状态的:Reachability github链接 可以获取是wifi还是3G网络,但此库依据查看有没有ip地址,这就造成了连上wifi,但是wifi上不了网的情况下,依然返回网络可连接的结果 ...
  • iOS指纹解锁Swift

    2017-06-14 15:53:45
    iOS指纹解锁 Swift,几行代码就搞定
  • ios Swift 页面跳转

    2020-02-27 01:41:24
    1. Main.storyBoard 定义 id 直接设置当前页面 ///获取故事版对象 let storyboard = UIStoryboard(name: "Main", bundle: nil) ///通过id获取UIViewController 强制转换成ViewController ...
  • swift"] // // ViewController.swift // Calculator // // Created by aecc on 2017/3/12. // Copyright © 2017年 aecc. All rights reserved. // import UIKit class ViewController...
1 2 3 4 5 ... 20
收藏数 10,824
精华内容 4,329