美文网首页
Swift - SnapKit 九宫格实现

Swift - SnapKit 九宫格实现

作者: ProfessorFan | 来源:发表于2018-09-07 15:27 被阅读471次

分析九宫格

1.多少行,多少列
2,每个单元View的宽度,每个单元View的高度
3.列间距,行间距
4.整个所有九宫格面板大小

最终我决定用SnapKit 布局来完成灵活的九宫格

文件说明

1.unitView.swift 这个文件就是一个单元View ,就是九宫格每一个item View,可以自己定义
2.BaseView.swift 这个文件是九宫格View 布局代码
3.ViewController.swift 这个文件是整么使用BaseView.swift
4.Double+extension.swift 这个文件是本人写的一个工具类,方便数据类型的转换

关键代码浏览

UnitView.swift

import UIKit

class UnitView: UILabel {

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.textAlignment = .center
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

BaseView.swift

import UIKit
import SnapKit
class BaseView: UIView {

    /** 列数  */
    var colums:Int = 3
    
    /** 左边间距  */
    var leftMargin:CGFloat = 0.0
    
    /** 右边间距  */
    var rightMargin:CGFloat = 0.0
    
    /** 上边间距  */
    var topMargin:CGFloat = 0.0
    
    /** 底部边间距  */
    var bottomMargin:CGFloat = 0.0
    
    /** colums(每一列之间的间距)间距  */
    var columsMargin:CGFloat = 0.0
    
    /** row(每一行之间的间距)间距  */
    var rowMargin:CGFloat = 0.0
    
     /** 单元View的高度  */
    var unitViewHeight:CGFloat = 50.0
    
    /**  数据源  */
    var titleArray:[String]? {
        
        didSet {
            
            //这里我们需要创建UnitView  对象了
            
            for item in titleArray! {
                
                let tempView = UnitView()
                self.addSubview(tempView)
                unitViewArray.append(tempView)
                tempView.text = item
                tempView.backgroundColor = .white
            }
            
        }
        

    }
    
    var unitViewArray:[UnitView] = [UnitView]()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initData()
        
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        let itemW = (self.bounds.size.width - self.leftMargin - self.rightMargin - (self.colums - 1).wd_CGFloat * self.columsMargin) / (self.colums.wd_CGFloat)
        
        let itemH = self.unitViewHeight
        
        var row = 0,colum = 0
        
        
        for i in 0...self.unitViewArray.count - 1 {
            
            row = i / self.colums
            colum = i % self.colums
            
            self.unitViewArray[i].snp.makeConstraints { (make) in
                
                make.leading.equalTo(self).offset((self.leftMargin + (self.columsMargin + itemW) * colum.wd_CGFloat))
                make.top.equalTo(self).offset((self.topMargin + (itemH + self.rowMargin)*row.wd_CGFloat ))
                make.width.equalTo(itemW)
                make.height.equalTo(itemH)
                
                if i == self.unitViewArray.count - 1 {
                    make.bottom.equalTo(self.snp.bottom).offset(-1.wd_CGFloat * self.bottomMargin)
                    
                }
                
            }
            
            
        }
        
    }

}

extension BaseView {
    
    func initData() -> () {
        
        self.colums = 3
        self.leftMargin = 10.0
        self.rightMargin = 10.0
        self.topMargin = 10.0
        self.bottomMargin = 10.0
        self.columsMargin = 10.0
        self.rowMargin = 10.0
        
    }
    
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    let currentView = BaseView(frame: CGRect.zero)
    
    override func viewDidLoad() {
        super.viewDidLoad()
      
        self.view.addSubview(currentView)
        
        currentView.backgroundColor = .red
        currentView.titleArray = ["你好吗","你好吗","你好吗","你好吗","你好吗","你好吗","你好吗","你好吗","你好吗","你好吗"];
        currentView.leftMargin = 10
        currentView.colums = 3
        currentView.topMargin = 10
        currentView.bottomMargin = 10
        currentView.columsMargin = 10
        currentView.rowMargin = 10
        
        currentView.snp.makeConstraints { (make) in
            
            make.leading.equalTo(self.view).offset(20)
            make.top.equalTo(self.view).offset(100)
            make.trailing.equalTo(self.view).offset(-20)
            
        }

    }

}

工具类
Double+extension.swift

import Foundation
import UIKit

//MARK:⚠️当我们在大数转小数的时候,可能出现越界问题导致程序奔溃
//MARK:例如:12333333333333333333333333333333.33  转 Int8 就会奔溃
extension Double {
   
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
    
    
}
extension Float {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension Int {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension Int8 {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension Int16 {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension Int32 {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension Int64 {
    
    var wd_Double: Double {
        return Double.init(self)
    }
    
    var wd_Int: Int {
        return Int.init(self)
    }
    
    var wd_Float:Float {
        
        return Float.init(self)
    }
    
    var wd_CGFloat:CGFloat {
        
        return CGFloat.init(self)
        
    }
    
    var wd_Int8:Int8 {
        
        return Int8.init(self)
    }
    
    var wd_Int16:Int16 {
        
        return Int16.init(self)
    }
    
    var wd_Int32:Int32 {
        
        return Int32.init(self)
    }
    
    var wd_Int64:Int64 {
        
        return Int64.init(self)
    }
}

extension CGRect {
    
    
    /// 这个任意类型只支持 CGFloat,String,Float,Int,Double,如果不是以上类型,x,y,width,height 的值都为 0
    ///
    /// - Parameters:
    ///   - x: 坐标x
    ///   - y: 坐标y
    ///   - width: 宽度
    ///   - height: 高度
    init(x: Any, y: Any, width: Any, height: Any) {
        self.init()

        func isInt(temp:Any) -> (Bool) {
            return temp is Int
        }
        
        func isDouble(temp:Any) -> (Bool) {
            return temp is Double
        }
        
        func isFloat(temp:Any) -> (Bool) {
            return temp is Float
        }
        
        func isCGFloat(temp:Any) -> (Bool) {
            
            return temp is CGFloat
        }
        
        func isString(temp:Any) -> (Bool) {
            return temp is String
        }
        
        var endX:Double = 0
        var endY:Double = 0
        var endWidth:Double = 0
        var endHeight:Double = 0
        
        if isString(temp: x) {
            
            let strX = x as! String
            endX = Double(strX)!
        } else if isDouble(temp: x) {
            
            let doubleX = x as! Double
            
            endX = Double.init(doubleX)
            
        } else if isFloat(temp: x) {
            
            let floatX = x as! Float
            
            endX = Double.init(floatX)
            
        } else if isCGFloat(temp: x) {
            
            let cgfloatX = x as! CGFloat
            endX = Double.init(cgfloatX)
            
        } else if isInt(temp: x) {
            
            let intX = x as! Int
            endX = Double.init(intX)
            
        } else {
            
            
        }
        
        if isString(temp: y) {
            
            let strY = y as! String
            endY = Double(strY)!
        } else if isDouble(temp: y) {
            
            let doubleY = y as! Double
            
            endY = Double.init(doubleY)
            
        } else if isFloat(temp: y) {
            
            let floatY = y as! Float
            
            endY = Double.init(floatY)
            
        } else if isCGFloat(temp: y) {
            
            let cgfloatY = y as! CGFloat
            endY = Double.init(cgfloatY)
            
        } else if isInt(temp: y) {
            
            let intY = y as! Int
            endY = Double.init(intY)
            
        } else {
            
            
        }
        
        if isString(temp: height) {
            
            let strH = height as! String
            endHeight = Double(strH)!
        } else if isDouble(temp: height) {
            
            let doubleH = height as! Double
            
            endHeight = Double.init(doubleH)
            
        } else if isFloat(temp: height) {
            
            let floatH = height as! Float
            
            endHeight = Double.init(floatH)
            
        } else if isCGFloat(temp: height) {
            
            let cgfloatH = height as! CGFloat
            endHeight = Double.init(cgfloatH)
            
        } else if isInt(temp: height) {
            
            let intH = height as! Int
            endHeight = Double.init(intH)
            
        } else {
            
            
        }
        
        if isString(temp: width) {
            
            let strW = width as! String
            endWidth = Double(strW)!
        } else if isDouble(temp: width) {
            
            let doubleW = width as! Double
            
            endWidth = Double.init(doubleW)
            
        } else if isFloat(temp: width) {
            
            let floatW = width as! Float
            
            endWidth = Double.init(floatW)
            
        } else if isCGFloat(temp: width) {
            
            let cgfloatW = width as! CGFloat
            endWidth = Double.init(cgfloatW)
            
        } else if isInt(temp: width) {
            
            let intW = width as! Int
            endWidth = Double.init(intW)
            
        } else {
            
        }
        
        self.init(x: endX, y: endY, width: endWidth, height: endHeight)
    }

}

SuperD总结

1.九宫格View 最重要的是建立一个View 的集合,之后用for 循环遍历来设置每一个View相对于最顶部 和最左边的距离.
2.里面这个分类个人觉得还是比较low 为了方便开发,不想每次都要注意类型CGRect(x:Any,y:Any,width:Any,height:Any)这个方法,个人觉得方便

相关文章

网友评论

      本文标题:Swift - SnapKit 九宫格实现

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