美文网首页Swift编程
15.Swift3.0版爱鲜蜂

15.Swift3.0版爱鲜蜂

作者: yaoyao妖妖 | 来源:发表于2017-08-21 10:52 被阅读52次
    前言:在学习Swift的过程中,在网上找到一个swift版的爱鲜蜂工程(http://www.jianshu.com/p/879f58fe3542#),十分感谢大神慷慨的分享。但是这个项目是Swift2.0版的,无法正常运行,花了一天的时间将这个项目改成3.0版可以正常使用的项目。其中各种坑。。。。但是还好最后终于可以正常使用了。

    下面来介绍一下在2.0转到3.0的过程中,遇到的各种bug。
    标注:下面会将改好的工程传到github上面,仅供学习,不做他用。
    修改后的版本的github地址,请使用Xcode 8.0打开,9打开会一直提示你升级swift4,而且一些xib支持也会有点问题。
    https://github.com/yaoyao66/-swift3.0.git

    1.首先是最坑的一个,在解析JSON数据的时候,遍历模型字典返回数据为空?
    • 最后发现判断一个可选择类型的对象是数组还是字典的方法出错了,在Swift2.0中使用
     let type = "\(value.self?.classForCoder)"  //获取当前对象的类型
    

    但是这个方法在swift3.0中这个返回的值不是 NSDictionary或者 NSArray 字符串,所以我将这部分直接改成

     if value is NSDictionary  //判断这个可选类型对象的类型是否是NSDictionary
     else if value is NSArray
    
    2.Swift编译时报错:Command failed due to signal: Segmentation fault: 11
    这个我首先用的是Xcode Beta9版的,你只要选择Xcode8版本的就可以了。
    
    3.Xcode8版本的模拟器不见了?
    应该是你打开了多个Xcode,将所有的Xcode和模拟器全部关掉,重新打开就可以了
    
    4. 方法发生了变化
    let p1 = transitionLayer.position;
    let p3 = CGPoint(x: view.width - 40, y: self.view.layer.bounds.size.height - 40);
            
    let positionAnimation = CAKeyframeAnimation(keyPath: "position")
    let path = CGMutablePath();
            
    //  CGPathMoveToPoint(path, nil, p1.x, p1.y);
    //  CGPathAddCurveToPoint(path, nil, p1.x, p1.y - 30, p3.x, p1.y 
    - 30, p3.x, p3.y);
    替换为
    path.move(to: CGPoint(x:p1.x,y:p1.y));
    path.addCurve(to: CGPoint(x:p3.x,y:p3.y), control1: CGPoint(x:p1.x,y:p1.y - 30), control2: CGPoint(x:p3.x,y:p1.y - 30));
    
    positionAnimation.path = path;
    
    5.override func animationDidStop(_ anim: CAAnimation, finished flag: Bool) 报下面的错误 Method does not override any method from its superclass

    这是因为animationDidStop是CAAnimationDelegate里面的方法,所以在class加上CAAnimationDelegate代理,然后去掉override关键字就好了

    6.sd_setImage(with:placeholderImage:completed:)' 报下面的错误 Ambiguous use of 我查了一下资料,好像是有sd_setImage有2个方法太相近了,所以才会出现这个错误

    代码修正为

    backImageView.sd_setImage(with:URL(string: imageName!),placeholderImage: UIImage(named: placeholderImageName!),options:SDWebImageOptions()) { (image, error,_ ,_ ) in
    
    
    7. Swift3.0中采用下面的方法来判断代理是否实现
     if (delegate.customClassMapping != nil)
    
    例子
    swift2.0
    if tmpSelf!.delegate != nil && ((tmpSelf!.delegate?.responds(to: #selector(HomeTableHeadViewDelegate.tableHeadView(_:iconClick:)))) != nil) 
    swift3.0  ?代替responds
    if ((tmpSelf!.delegate?.tableHeadView(_:iconClick:)) != nil) 
    
    用weak定义代理
    weak var delegate:DelegateName?
    
    // - MARK: Delegate
    //在Swift中,制定协议需要遵守NSObjectProtocol协议,除了类可以遵守协议,结构体也可以遵守协议
    @objc protocol HomeTableHeadViewDelegate: NSObjectProtocol {
        @objc optional func tableHeadView(_ headView: HomeTableHeadView, focusImageViewClick index: Int)
        @objc optional func tableHeadView(_ headView: HomeTableHeadView, iconClick index: Int)
    }
    
    8. Swift3.0中通知
    NotificationCenter.default.addObserver(self, selector: #selector(HomeViewController.homeTableHeadViewHeightDidChange(_:)), name: NSNotification.Name(rawValue: HomeTableHeadViewHeightDidChange), object: nil)
    NotificationCenter.default.post(name: Notification.Name(rawValue: HomeTableHeadViewHeightDidChange), object: newValue)
    
    9. Swift3.0中的逃逸闭包

    如果闭包被作为参数传递到函数时,该闭包不需要立即执行而是需要等某些线程完成任务之后再执行,那么需要在该闭包前加上@escaping,否则编译器报错。如下代码所示:

        convenience init(frame: CGRect, iconClick:@escaping ((_ index: Int) -> Void)) {
            self.init(frame:frame)
            self.iconClick = iconClick
        }
    
    10.Swift3.0循环
    //正序  0...2    0 1  2       0 ..<2   0 1
      for i in 0...2 {
                let btn = UIButton()
    }
    
    //倒序
     if subviews.count>1 {//在这里需要注意subviews.count的值一定要大于1,不然会出现错误
                    for i in (1...subviews.count).reversed() {
                        let subBtnView = self.subviews[i-1]
                        subBtnView.removeFromSuperview()
                    }
                }
    
    11.Swift3.0循环Block
    HotView.swift
    var iconClick:((_ index: Int) -> ())?   //声明并定义一个block
    convenience init(frame: CGRect, iconClick:@escaping ((_ index: Int) -> Void)) {
            self.init(frame:frame)
            self.iconClick = iconClick
        }
    
    //点击事件
     func iconClick(_ tap: UITapGestureRecognizer) {
            if iconClick != nil {
                iconClick!(tap.view!.tag)
            }
        }
    
    //页面上添加手势
    let tap = UITapGestureRecognizer(target: self, action:#selector(HotView.iconClick(_:)))
                        icon.addGestureRecognizer(tap)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //点击页面,block回调
    func buildHotView() {
            weak var tmpSelf = self
            hotView = HotView(frame: CGRect.zero, iconClick: { (index) -> Void in
               if ((tmpSelf!.delegate?.tableHeadView(_:iconClick:)) != nil) {
                    tmpSelf!.delegate!.tableHeadView!(tmpSelf!, iconClick: index)
                }
            })
            hotView?.backgroundColor = UIColor.white
            addSubview(hotView!)
        }
    
    12.Swift3.0常用控件
    //UIButton
     let btn = UIButton()
     btn.setTitle(buttonTitles[i], for: UIControlState())
     btn.backgroundColor = UIColor.white
     btn.layer.cornerRadius = 5
     btn.tag = i
     btn.titleLabel?.font = UIFont.systemFont(ofSize: 10)
     btn.frame = CGRect(x: 30 + CGFloat(i) * ((ScreenWidth - btnW * 3 - 60) / 2 + btnW), y: blogLabel.frame.maxY + 10, width: btnW, height: 30)
     btn.addTarget(self, action: #selector(AboltAuthorViewController.btnClick(_:)), for: UIControlEvents.touchUpInside)
    btn.setTitleColor(UIColor.black, for: UIControlState())
    view.addSubview(btn)
    
    
    //UILabel
      let buyCountLabel = UILabel()
      buyCountLabel.isHidden = false
      buyCountLabel.text = "0"
      buyCountLabel.textColor = UIColor.black
      buyCountLabel.textAlignment = NSTextAlignment.center
      buyCountLabel.font = HomeCollectionTextFont
      return buyCountLabel
    
    
    13.didSet

    属性观察者,类似于触发器。用来监视属性的除初始化之外的属性值变化,当属性值发生改变时可以对此作出响应。有如下特点:

    • 1 不仅可以在属性值改变后触发didSet,也可以在属性值改变前触发willSet。
    • 2 给属性添加观察者必须要声明清楚属性类型,否则编译器报错。
    • 3 willSet可以带一个newName的参数,没有的话,该参数默认命名为newValue。
    • 4 didSet可以带一个oldName的参数,表示旧的属性,不带的话默认命名为oldValue。
    • 5 属性初始化时,willSet和didSet不会调用。只有在初始化上下文之外,当设置属性值时才会调用。
    • 6 即使是设置的值和原来值相同,willSet和didSet也会被调用
    //普通属性
        var firstName:String = ""
        var lastName:String  = ""
        var nickName:String  = ""
    //计算属性
        var fullName:String
        {
            get
            {
                return nickName + " " + firstName + " " + lastName
            }
        }
    //带属性监视器的普通属性
    
        var age:Int = 0 {
         //我们需要在age属性变化前做点什么
            willSet
            {
                print("Will set an new value \(newValue) to age")
            }
            didSet {
              print("age filed changed form \(oldValue) to \(age)")
                if age<10
                {
                    nickName = "Little"
                }else
                {
                    nickName = "Big"
                }
            }
        }
    //调用
    let me = People()
    me.firstName = "Li"
    me.lastName  = "Lei"
    me.age = 30
    
    14.Swift3.0速查手册

    https://darielchen.github.io/SwiftManual/

    相关文章

      网友评论

        本文标题:15.Swift3.0版爱鲜蜂

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