贡献作者 -【XJDomain】
博客XJ: https://my.oschina.net/shengbingli/blog
GitHub直播地址: https://github.com/lishengbing/XJDomainLive
1:自定义控制器,重写控制器的init方法
>实现的必要方法:外部传入参数,内部使用一个属性接收这个参数保存起来即可
>注意: 控制器是调用: super.init(nibName: nil, bundle: nil)
// MARK: - 自定义函数
init(kTargetRight : CGFloat) {
super.init(nibName: nil, bundle: nil)
self.targetRight = kTargetRight
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
2:如果一个视图上有很多手势,要想静止这些手势和点击之类的,只需要静止这个视图的交互即可
(self.parent as! CHHomeIndexViewController).mainView.isUserInteractionEnabled = false
3:自定义视图,重写init方法
>实现的必要方法:也是在内部里面定义一个属性保存这个外部传来的参数
>注意:自定义View是调用: super.init(frame: frame)
// MARK: - 自定义构造函数
init(frame: CGRect, titles: [String]) {
self.titles = titles;
super.init(frame: frame)
// 设置UI界面
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
4:在一个View上添加一个collectionView的话情况!!!
!!! 注册和修改内边距是在awakeFromNib()方法中实现中
!!! 修改collectionView的itemSize的话需要在layoutSubViews方法中实现
// 系统回调函数
override func awakeFromNib() {
super.awakeFromNib()
// 让控件不随着父控件的拉伸而拉伸
autoresizingMask = UIViewAutoresizing()
// 注册cell
collectionView.register(UINib(nibName: "XJGameCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: kGameCellID)
// 给collectionView添加内边距
collectionView.contentInset = UIEdgeInsetsMake(0, kEdgeInsetMargin, 0, kEdgeInsetMargin)
}
override func layoutSubviews() {
super.layoutSubviews()
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: 80, height: collectionView.bounds.size.height)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
collectionView.showsHorizontalScrollIndicator = false
}
5:一个View从Xib中加载视图的话情况!!!
一般需要快速创建一个类方法加载,如下:
// MARK: - 快速创建的类方法
extension XJRecommendGameView {
class func recommendGameView() -> XJRecommendGameView {
return Bundle.main.loadNibNamed("XJRecommendGameView", owner: nil, options: nil)?.first as! XJRecommendGameView
}
}
6:ios10以后保存图片到本地默认相册的方法:
@objc fileprivate func saveClick() {
// 1:获取当前显示的图片
let cell = collectionView.visibleCells.first as! XJPhotoBrowerCollectionViewCell
guard let image = cell.imageView.image else { return }
// 2:将image对象保存相册使用这个方法
/*
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
*/
// 这个方法不行,用上面的方法
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(image:didFinishSavingWithError:contextInfo:)), nil)
}
@objc fileprivate func image(image : UIImage, didFinishSavingWithError error : Error?, contextInfo : Any) {
var showInfo = ""
if error != nil {
showInfo = "保存失败"
}else {
showInfo = "保存成功"
}
SVProgressHUD.setMinimumDismissTimeInterval(0.5)
SVProgressHUD.showSuccess(withStatus: showInfo)
}
7:获取当前显示的cell方法:
// 获取当前显示的cell
print("111")
let cell = collectionView.visibleCells.first as! XJPhotoBrowerCollectionViewCell
// 获取当前显示的cell
let cell = collectionView.visibleCells.first as! XJPhotoBrowerCollectionViewCell
// 返回当前cell的下标值
return collectionView.indexPath(for: cell)!
8:如果在一个控制器中纯代码创建collectionView的情况!!!
> 一般情况下是在setupUI中设置itemSize约束
> 另外一种方式:自己自定义布局即可
// 懒加载控件
fileprivate lazy var collectionView : UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: XJPhotoBrowerCollectionViewLayout())
// MARK: - 自定义布局
class XJPhotoBrowerCollectionViewLayout : UICollectionViewFlowLayout {
override func prepare() {
super.prepare()
itemSize = collectionView!.frame.size
// 设置itemSize属性
minimumInteritemSpacing = 0
minimumLineSpacing = 0
scrollDirection = .horizontal
// 设置collectionView属性
collectionView?.isPagingEnabled = true
collectionView?.showsHorizontalScrollIndicator = false
collectionView?.showsVerticalScrollIndicator = false
collectionView?.bounces = false
}
}
9:设置滚动视图需要在一半的情况切换情况!!!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// 1.1我们可以设置当滚动到一半的时候就会显示下一个下标即可
let offsetX = scrollView.contentOffset.x + scrollView.bounds.width * 0.5
// 2.设置label
let index = Int(offsetX / scrollView.bounds.size.width)
label.text = "\(index + 1) / \(images.count)"
}
10:自定义进度条View,绘画扇形至完整,根据进度!!!
import UIKit
class XJProgressView: UIView {
var progress : CGFloat = 0 {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
super.draw(rect)
// 获取参数
let center = CGPoint(x: rect.width * 0.5, y: rect.height * 0.5)
let radius = rect.width * 0.5 - 3
let startangle = CGFloat(-M_PI_2)
let endAngle = CGFloat(M_PI * 2) * progress + startangle
// 创建贝塞尔曲线
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startangle, endAngle: endAngle, clockwise: true)
// 绘制一条中心点的线
path.addLine(to: center)
path.close()
// 设置绘制的颜色
UIColor.white.withAlphaComponent(0.4).setFill()
// 开始绘制 path.stroke() 这是绘制空心
path.fill()
}
}
11:如果重写构造函数的话,如果也需要使用init()方法的话,就需要重新init()方法,不然外面不能调用使用
见:XJWeiBo -> XJPopoverAnimator类说明
// 设置闭包
var callBack : ((_ isPresented : Bool) -> ())? = nil
// 自定义构造函数
// 注意:如果不重写默认的init()方法的话,外面创建对象的时候是没有objc()这个方法的,因为自定义构造函数覆盖了默认的init()方法,除非重写默认的 init()方法即可
override init() {
super.init()
}
init(callBack : @escaping (_ isPresented : Bool) -> ()) {
self.callBack = callBack
}
12:使用Kingfisher缓存保存图片
// 缓存图片<为了先下载完成再刷新表格:可以加入到线程组中,等线程组结束,然后线程完成通知再次刷新即可>
fileprivate func cacheImage(statusA : [XJStatusModel], _ finishedCallBack : @escaping () -> ()) {
// 1.创建组
let group = DispatchGroup()
// 缓存图片
for statusModel in statusA {
for picUrl in statusModel.picUrlArray {
// 进入组
group.enter()
let down = KingfisherManager.shared.downloader
down.downloadImage(with: picUrl, options: [], progressBlock: nil, completionHandler: { (_, _, _, _) in
// 离开组
group.leave()
})
}
}
// 返回数据
group.notify(queue: DispatchQueue.main) {
finishedCallBack()
}
}
13:从Kingfisher缓存中提取照片
// 1.从缓存中取出下载图片
let cacheImg = KingfisherManager.shared.cache
let urlString = status?.picUrlArray.first?.absoluteString
guard let image = cacheImg.retrieveImageInDiskCache(forKey: urlString!) else { return CGSize.zero}
14: 获取cell上的相对Window的坐标<转移坐标系>
// 1:获取cell
let cell = cellForItem(at: indexPath)!
// 2:获取cell的frame 转移坐标系 convert(<#T##point: CGPoint##CGPoint#>, to: <#T##UICoordinateSpace#>)
let starFrame = self.convert(cell.frame, to: UIApplication.shared.keyWindow)
15:字典中的字典转模型处理
// MARK: - 自定义构造函数
init(dict : [String : Any]) {
super.init()
setValuesForKeys(dict)
// 1.将用户字典中中user对象转成个人模型:二级字典转模型
if let userDict = dict["user"] as? [String : Any] {
user = XJUserModel(dict: userDict)
}
// 2.将转发微博专为模型
if let retweetedDict = dict["retweeted_status"] as? [String : Any] {
retweeted_status = XJStatusModel(dict: retweetedDict)
}
}
16:字符串的截取处理
// 2.对的字符串进行处理
// <a href=\"http://app.weibo.com/t/feed/5yiHuw\" rel=\"nofollow\">iPhone 6 Plus</a>
let statrIndex = (source as NSString).range(of: ">").location + 1
let length = (source as NSString).range(of: "</").location - statrIndex
sourceText = (source as NSString).substring(with: NSRange(location: statrIndex, length: length))
17:后期不断更新......