swift中SnapKit以及Kingfisher的使用

前言

ios 开发过程中,难免会用到一些三方库,这里介绍一下 swift 开发过重中常用的自适应布局 SnapKit 和 图片异步加载框架 Kingfisher 的使用

其中 Kingfisher 就是比较出名的 onevcat 写的,可以替换 SDWebImage,而 SnapKit 就是 Object-c 开发中比较常用的 masonryswift版本,案例以及对应三方库github地址如下所示

案例demokingfisherSnapKit

SnapKit

UI自适应布局框架,其采用链式风格开发,在swift中就更加顺风顺水了,需要先添加到视图中,在进行布局设定,一些参数预留之后,会根据内容自动拉伸,案例代码如下

let bkg = UIView()
bkg.backgroundColor = UIColor(named: "theme_color")


self.view.addSubview(bkg)
bkg.snp.makeConstraints { make in
    make.left.equalTo(self.view).offset(15)
    make.right.equalTo(self.view).offset(-15)
    make.top.equalTo(100)
}

bkg.addSubview(self.ivHeader)
self.ivHeader.snp.makeConstraints { make in
    make.left.top.equalTo(10)
    make.bottom.equalTo(bkg).offset(-10) //相对于bkg的底部 10 像素,右和下贴近内部都是负的
    make.width.height.equalTo(120)
}

self.lblUseName.text = "哈哈哈哈哈哈"
self.lblUseName.numberOfLines = 0;
self.lblUseName.sizeToFit() //自适应换行
self.view.addSubview(self.lblUseName)
self.lblUseName.snp.makeConstraints { make in
    make.left.equalTo(self.ivHeader.snp.right).offset(10)
    make.centerY.equalTo(self.ivHeader.snp.centerY)
}

另外,开发过程中,可能会经常碰到两个内容需要争夺一片固定空间的时候,那么需要一个优先级,让优先级高的内容先显示全了,剩余空间交给另外一个(和 flex 布局中的 flex: 1 很像),那么可以像下面代码一样使用,平时使用过程中的场景(例如:评论中的用户名和一些附加信息,可能需要先显示全部分附加信息,再显示可长可短的用户名,然后根据剩余空间决定其他附加信息的长短或者是否显示)

//第二个参数是指的方向.horizontal水平、.vertical垂直,第一个参数值的是权限
//设置拥抱权限等级,有好几个,一般使用 .required、.defaultHigh、.defaultLow,中间也有其他一般这就够了
//不设置默认为.required优先级1000,其他两个分别750、250,可以点进去看看
//hug有拥抱的意思,指的是拥抱权限,即抗拉伸的权限
self.lblUseName.setContentHuggingPriority(.required, for: .horizontal)
//设置耐挤压,即抗挤压的权限
self.lblUseName.setContentCompressionResistancePriority(.required, for: .horizontal)

Kingfisher

Kingfisher 就是 Swift 版本的 SDWebImage(异步加载图片框架),此外还增加了一些常用小功能,options 里面可以添加很多小功能,可以点进去查看自己想要的,案例列举除了一些比较常用的功能(更重要的是,大家一直纠结的不同版本的离屏渲染的圆角问题,这里可以将图片直接裁剪,因此也不用纠结那么多了),使用如下所示

//使用默认图片
let url = URL(string: "https://pic.leetcode-cn.com/1654836514-AIOwwN-1627640862-HgXcTO-Frame%201444.jpeg?x-oss-process=image%2Fformat%2Cwebp")
//self.ivHeader.kf.setImage(with: url)

//设置占位
let image = UIImage(named: "logo");
//self.ivHeader.kf.setImage(with: url, placeholder: image)

//加工设置圆角,默认没有圆角,这样可以避免设置圆角的一些性能问题
let processor = DownsamplingImageProcessor(size: CGSize(width: 120, height: 120))
             |> RoundCornerImageProcessor(cornerRadius: 60)
//可以设置很多属性,可以点进去查看
self.ivHeader.kf.setImage(with: url, placeholder: image, options: [
    .processor(processor), //加工图像
    .scaleFactor(UIScreen.main.scale), //像素倍率scale
    .transition(.fade(1)), //渐变动画
    .loadDiskFileSynchronously,//从磁盘同步加载 .cacheMemoryOnly()仅仅内存缓存
    .cacheOriginalImage
]) { result in
    //加载结束后的回调,如果需要除了,可以在这里处理
    switch result {
    case .success(let value):
        print("Task done for: \(value.source.url?.absoluteString ?? "")")
    case .failure(let error):
        print("Job failed: \(error.localizedDescription)")
    }
}
//设置指示器
self.ivHeader.kf.indicatorType = .activity //.none没有

此外,如果需要手动控制加载时机(例如:大图加载优化、仅仅下载),可以使用 ImageDownloader 来下载,然后处理回调相关

//如果有大图加载优化等需求,或者其他根据其他情况自行处理下载的图片,可以走downLoad
//也有options和其他逻辑,可以根据需要使用
ImageDownloader.default.downloadImage(with: url!) { [weak self]result in
    switch result {
    case .success(let value):
        self?.ivHeader.image = value.image
    case .failure(let error):
        print(error)
    }
}

最后

看看效果图吧,就不做太多案例了,毕竟使用确实很简单,另外api使用越简单,那么源码就越复杂,源码才是我们需要深层次探究的

image.png

猜你喜欢

转载自juejin.im/post/7123939974612779044