项目笔记

2019-07-30  本文已影响0人  苹果上的小豌豆

项目笔记

1. framework风格架构


2. Swift.Error枚举

public enum FCNetworkError: Swift.Error {
  case jsonMapping(response: Moya.Response)
  case businessCode(json: SwiftyJSON.JSON, message: String?)
  case attributeExists(json: SwiftyJSON.JSON, message: String?)
  case networkError(code: Int, message: String?)
    }


3. Notification封装

public enum NotificationKeys: String {
   case workOrderStatusChange = "WorkOrderStatusChange"
}
extension NotificationKeys {
private func name() -> Notification.Name {
    return Notification.Name(rawValue: self.rawValue)
}
}

extension NotificationKeys {

public func post(object: Any? = nil, userInfo: [AnyHashable: Any]? = nil) {
    NotificationCenter.default.post(name: self.name(), object: object, userInfo: userInfo)
}

public func addObserver(_ observer: Any, selector: Selector, object: Any? = nil) {
    NotificationCenter.default.addObserver(observer, selector: selector, name: self.name(), object: object)
}

public func removeObserver(_ observer: Any) {
    NotificationCenter.default.removeObserver(observer, name: self.name(), object: nil)
}
 }

extension Notification.Name {
public func post(object: Any? = nil, userInfo: [AnyHashable: Any]? = nil) {
    NotificationCenter.default.post(name: self, object: object, userInfo: userInfo)
 }

public func addObserver(_ observer: Any, selector: Selector, object: Any? = nil) {
    NotificationCenter.default.addObserver(observer, selector: selector, name: self, object: 
object)
}

public func removeObserver(_ observer: Any) {
    NotificationCenter.default.removeObserver(observer, name: self, object: nil)
}
 }


4. 压缩图片方法

///压缩图片上传
fileprivate func  compressImageToSuitableSize(compressImage: UIImage, compressvalue compressionQuality: CGFloat = 0.8) -> Data? {
    
    var actualHeight: CGFloat = compressImage.size.height
    var actualWidth: CGFloat = compressImage.size.height
    let maxHeight: CGFloat = kCompressImageInitDefaultMaxHeight
    let maxWidth: CGFloat = kCompressImageInitDefaultMaxWidth
    var imageRatio: CGFloat = actualWidth / actualHeight
    let maxRatio: CGFloat = maxWidth / maxHeight
    
    if actualHeight >= maxHeight || actualWidth >= maxWidth {
        
        if imageRatio < maxRatio {
            ///根据最大高度来调整实际宽度
            imageRatio = maxHeight / actualHeight
            actualWidth = imageRatio * actualWidth
            actualHeight = maxHeight
        } else if imageRatio > maxRatio {
            ///根据最大宽度来调整实际高度
            imageRatio = maxWidth / actualWidth
            actualHeight = imageRatio * actualHeight
            actualWidth = maxWidth
        } else {
            actualHeight = maxHeight
            actualWidth = maxWidth
        }
    }
    
    let rect = CGRect(x: 0.0, y: 0.0, width: actualWidth, height: actualHeight)
    UIGraphicsBeginImageContext(rect.size)
    compressImage.draw(in: rect)
    guard let lastImage = UIGraphicsGetImageFromCurrentImageContext() else {
            UIGraphicsEndImageContext()
        return UIImageJPEGRepresentation(compressImage, compressionQuality)
    }
    guard let imageData = UIImageJPEGRepresentation(lastImage, compressionQuality) else {
            UIGraphicsEndImageContext()
        return UIImageJPEGRepresentation(lastImage, compressionQuality)
    }
            UIGraphicsEndImageContext()
    return imageData
}


5. [Realm-Swift] 数据库的使用详解

总结一下:初始化创建实例对象,给对象赋值,数据持久化write写入,读取,删除,新增。

    //用户头像
class HeadPortrait:Object {
//图片数据
 @objc dynamic var data:Data?
 
//创建时间
 @objc dynamic var date = Date()
}

 do {
            let data = try Data.init(contentsOf: url)
            model.imageData = data
            try Realm().write {
                realm.add(model, update: true)
            }   
        } catch let error {
            Log("失败:\(error.localizedDescription)")
        }

  guard let model = realm.object(ofType: HeadPortrait.self, forPrimaryKey: "1") else {
            return nil
 }

 do {
        let realm = try Realm()
        // 取已保存所有广告
        guard let model = realm.object(ofType: HeadPortrait.self, forPrimaryKey: "1") else {
            return nil
        }
      realm.beginWrite()
       realm.delete(model)
       try realm.commitWrite()
    } catch let error {
        Log("失败:\(error.localizedDescription)")
    }

6. AppDelegate第三方注册启动优化和封装

在AppDelegate中,一个大型项目会有很多第三方key值注册,比如友盟统计,第三方登录,个推,地图注册 等等,我们需要做一个 扩展,将代码整理,便于后期的维护和优化

如下:

image.png
1.在AppDelegate中只需要如下:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow.init(frame: UIScreen.main.bounds)
    window?.backgroundColor = UIColor.white
    window?.makeKeyAndVisible()
    
    self.performSetup(application, didFinishLaunchingWithOptions: launchOptions)

    return true
}
2.在扩展中进行下面的操作:
 extension AppDelegate {
func performSetup(_ application: UIApplication, didFinishLaunchingWithOptions 
                         launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
  /////umeng统计
  //友盟分享注册
  // 百度地图启动
  // 埋点统计

}

3.开辟一个线程,耗时操作不要在AppDelegate启动的时候进行:
 let backgroundQueue = DispatchQueue(label: "com.geselle.backgroundQueue", qos:     
 .background)
 backgroundQueue.async {
    //去做key的注册和第三方初始化
 }


7.SnapKit的进阶

优先级顺序是:required > high > medium > low



8.关于iOS相关动画

1.transform.translation.xX轴循环滚动

 let anim = CABasicAnimation.init()
    anim.keyPath = "transform.translation.x"
    anim.fromValue = self.bounds.origin.x
    anim.toValue = self.bounds.origin.x - 100
    anim.duration = CFTimeInterval(0.2)
    anim.repeatCount = MAXFLOAT
    anim.isRemovedOnCompletion = false
    
    anim.fillMode = CAMediaTimingFillMode.forwards;
    anim.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.linear)
    
    Layer.add(anim, forKey: nil)

2. transform.translation.y,Y轴循环滚动(Z轴,opacity)

let basicAnimation = CABasicAnimation(keyPath: "transform.translation.y")
    basicAnimation.fromValue = userImageView.origin.y - 5
    basicAnimation.toValue = userImageView.origin.y + 5
    basicAnimation.duration = 1.5
    basicAnimation.repeatCount = HUGE
    basicAnimation.fillMode = CAMediaTimingFillMode.forwards
    basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    View.layer.add(basicAnimation, forKey: nil)

3.动画的组合使用:

    let animation = CASpringAnimation()
    animation.keyPath = "position.y"
    animation.fromValue = UIScreen.main.bounds.height
    animation.toValue = cell.center.y
    // 质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大
    animation.mass = 1
    // 刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快
    animation.stiffness = 60
    // 阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快
    animation.damping = 10
    // 初始速率
    animation.initialVelocity = 0
    animation.fillMode = .forwards
    animation.isRemovedOnCompletion = false
    
    let alphaAni = CABasicAnimation()
    alphaAni.keyPath = "opacity"
    alphaAni.fromValue = 0
    alphaAni.toValue = 1
    
    let group = CAAnimationGroup()
    group.animations = [animation, alphaAni]
    group.duration = animation.settlingDuration
    group.fillMode = .forwards
    group.isRemovedOnCompletion = false
    cell.layer.add(group, forKey: "cell_reload")

比如另一个:

 let appearAnim = CABasicAnimation(keyPath: "opacity")
        appearAnim.delegate = self
        appearAnim.duration = duration
        appearAnim.fromValue = 0
        appearAnim.toValue = 1
        appearAnim.fillMode = .forwards
        appearAnim.isRemovedOnCompletion = false
        toView.layer.add(appearAnim, forKey: "toView_AppearAnim")

        let pushPositionAnim = CABasicAnimation(keyPath: "position.y")
        pushPositionAnim.duration = duration
        pushPositionAnim.delegate = self
        pushPositionAnim.fromValue = fromView.layer.position.y
        pushPositionAnim.toValue = fromView.layer.position.y-120
        pushPositionAnim.timingFunction = CAMediaTimingFunction(name: .easeOut)
        pushPositionAnim.fillMode = .forwards
        pushPositionAnim.isRemovedOnCompletion = false
        fromView.layer.add(pushPositionAnim, forKey: "push_Anim")

4.常规的动画:

UIView.animate(withDuration: 0.15, delay: 0.0, options: .curveEaseOut, animations: {
        
    }) { finshed in
    }

 UIView.animate(withDuration: 0.9, delay: delayTime, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .curveEaseInOut, animations: {
        self.frame = originalFrame
    }) { finished in
    }

   backView.transform = backView.transform.scaledBy(x: 0.5, y: 0.5)
    UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .beginFromCurrentState, animations: {
        self.backView.transform = .identity
        self.backView.alpha = 1
        self.alpha = 1
    }) { (finish) in
        
    }

5.第三方的框架:



9.虚线的画法

 private func drawDottedLine(_ view: UIView) {
    let layer = CAShapeLayer()
    layer.bounds = view.bounds
    layer.position = CGPoint(x: view.width * 0.5, y: view.height)
    layer.fillColor = UIColor.clear.cgColor
    layer.strokeColor = UIColor(0xe5e5e5).cgColor
    layer.lineWidth = view.height
    layer.lineJoin = kCALineCapRound
    layer.lineDashPattern = [NSNumber(value: 3), NSNumber(value: 1)]
    
    let path = CGMutablePath()
    path.move(to: CGPoint(x: 0, y: 0))
    path.addLine(to: CGPoint(x: view.width, y: 0))
    
    layer.path = path
    view.layer.addSublayer(layer)
}


10.PinLayout:一套极具新意,基于代码的布局框架库

【pinlayout】(https://github.com/layoutBox/PinLayout

【pinlayout掘金文档】(https://juejin.im/entry/59349400570c35005b52e429



11.利用RX做一些简单的按钮点击图片点击事件操作


上一篇 下一篇

猜你喜欢

热点阅读