1. 程式人生 > >IOS控制元件系列----使用UITableView實現網格佈局,自定義顯示列數

IOS控制元件系列----使用UITableView實現網格佈局,自定義顯示列數

先放一引效果圖:


在IOS中達到類似Android中的GridLayout 通常是使用UIConlectionView,這個元件是平果公司已經封裝好的,直接實現相應的介面即可。不知道各位道友是否也曾想過用UItableView來擼一個這個東西,這可能會有一點偏執,但對於致力於提高自己的人來說,不安於現狀,死喜歡用各種自定義的東西來“折騰”自己也不失為一種方式。

我本人就比較喜歡在閒時擼一些小框架,右邊是我的github地址  點選這裡有驚喜

想要用UITableView來呈現網格佈局需要解決如下幾個問題。

問題一:預設的UITableView行數顯示的是一個,即顯示一個UITableViewCell ,這個東西,不知道各位有使用的時候有沒有注意到你不需要設定它的frame ,它也能完美在呆在UIUItabVlew中,只因平果公司為我們做好了,在設定單元格高度的時候,就固定了UITableViewCell的frame

在實現這個介面的時候 ,需要我們返回一個高度值

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        
        return 70
    }
為了解決這個問題,我們曲線救國,既然UITableViewCell不然改變座標,那麼我們移動它內部的元素應該就行

UITableViewCell 個類擴充套件於UIView,看到UIView道友可能來興趣了,在IOS中有了UIView幾乎可以幹一切“壞事”

UIView有容乃大,

UITableViewCell

當作容器,然後自定義一個UIView作為UITableViewCell的子元素來呈現我們想要呈現的資料即可解決問題一

問題二:列數的展示?

先說一個題外話,UITableView的複用機制,是針對UITableViewCell而言的,對UITableViewCell內容的子元素並未做到複用優化,這裡我也沒有想到想到優化方案,如果你想到了,請留下你的評論,我們一起交流下

回到主題 --列數的應該是可以定義的,那麼當列數設定好之後,相應的顯示的行數也應該要進行變化,計算式子如下:

行數  = (資料列表的長度 -1)./ 列數 + 1

本案例程式碼為:

       
        rowNum = (dataList.count - 1) / colNum + 1
        
    }
    
    
    //implements protocol
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return rowNum
    }

問題三:之前使用UITableView時,將資料打到UITableViewCell上時,是按行進行繫結的,現在是一行顯示多列資料就需要重寫這個介面

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

使其在資料列表中取到正確索引的資料

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell : UITableViewCell = UITableViewCell()
        
        for i in 0..<colNum {
            
            if indexPath.row * colNum + i >= self.dataList.count {
            
                break;
            }
        
            let view : TestView = TestView()
            
            view.label.text = dataList[indexPath.row * colNum + i]
            
            view.label.textColor = UIColor.green
            
            view.frame = CGRect.init(x: i * 90 + 10, y: 0, width: 60, height: 40)
            
            cell.addSubview(view)
        }
        
        
        
        
        return cell
        
    }


一些該丟出去的屬性,這裡未做過多說明,相信你完全有這個能力將其美化,本案例權當拋磚引玉,介紹下設計思路:

完整程式碼如下:

import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
    lazy var tableView : UITableView = {() -> UITableView in
    
        var tabView : UITableView = UITableView.init(frame: CGRect.init(x: 0, y: 40, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        
        
        return tabView
    
    }()
    
    lazy var dataList : Array<String> = {() -> Array<String> in
    
        var arr : Array<String> = Array<String>()
        
        return arr
        
    }()
    
    let colNum : Int = 4
    
    var rowNum : Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        
        initView()
    }
    
    func initView() {
    
        tableView.delegate = self
        tableView.dataSource  = self
        self.view.addSubview(tableView)
        
        //初始化資料
        
        for i in 0..<13{
        
            dataList.append(String.init(format: "%d", i))
            
        }
        
        rowNum = (dataList.count - 1) / colNum + 1
        
    }
    
    
    //implements protocol
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return rowNum
    }
    
    
    //implements protocol
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        
        return 70
    }
    
    //implements protocol
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell : UITableViewCell = UITableViewCell()
        
        for i in 0..<colNum {
            
            if indexPath.row * colNum + i >= self.dataList.count {
            
                break;
            }
        
            let view : TestView = TestView()
            
            view.label.text = dataList[indexPath.row * colNum + i]
            
            view.label.textColor = UIColor.green
            
            view.frame = CGRect.init(x: i * 90 + 10, y: 0, width: 60, height: 40)
            
            cell.addSubview(view)
        }
        
        
        
        
        return cell
        
    }
    
    
    
    
    
    
    
    
    
    
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}