ios九宮格布局

一、item寬度相等

1.1、按鈕實現(xiàn)

  • 確定所需的一列item的最大個數(shù)
    static NSInteger const corlmax = 4;
  • 確定item之間的間距
    static CGFloat const margin = 20;
  • 計算item的寬度
    [UIScreen mainScreen].bounds.size.width-(corlmax - 1) * margin) / corlmax
  • 循環(huán)創(chuàng)建按鈕睹限,根據(jù)按鈕將要分布所在的行和所在的列確定x,y
    int row=i/corlmax;//所在行
    int col=i%corlmax;//所在列
    CGFloat x= (itemWH+margin)col;
    CGFloat y =(itemWH+margin)
    row;
    按鈕的總行數(shù): Rows = (count - 1) / cols + 1
    按鈕的總寬度:width=總列數(shù)一個寬度+(總列數(shù)-1)間距
    按鈕的總高度:height=總行數(shù)一個寬度+(總行數(shù)-1)間距
#import "ViewController.h"
static NSInteger const corlmax = 4;
static CGFloat const margin = 20;
#define itemWH ([UIScreen mainScreen].bounds.size.width-(corlmax - 1) * margin) / corlmax
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    for (int i = 0; i < 10; i++) {
        int row=i/corlmax;//所在行
        int col=i%corlmax;//所在列
        //創(chuàng)建按鈕
        UIButton *btn= [UIButton buttonWithType:UIButtonTypeCustom];
        btn.backgroundColor=[UIColor redColor];
        CGFloat x= (itemWH+margin)*col;
        CGFloat y =(itemWH+margin)*row;
        btn.frame=CGRectMake(x, y, itemWH,  itemWH);
        [self.view addSubview:btn];
    }
}

1.2、UICollectionview實現(xiàn)

#import "ViewController.h"
static NSInteger const cols = 4;
static CGFloat const margin = 10;
#define itemWH ([UIScreen mainScreen].bounds.size.width - 20-(cols - 1) * margin) / cols
static NSString * const ID = @"cell";
@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@property (nonatomic, weak) UICollectionView *collectionView;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    // 設(shè)置item尺寸
    layout.itemSize = CGSizeMake(itemWH, itemWH);
    layout.minimumInteritemSpacing = margin;
    layout.minimumLineSpacing = margin;
    // 創(chuàng)建UICollectionView
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 375, 667) collectionViewLayout:layout];
    [self.view addSubview:collectionView];
    collectionView.backgroundColor=[UIColor whiteColor];
    _collectionView = collectionView;
    collectionView.dataSource = self;
    collectionView.delegate=self;
    collectionView.scrollEnabled = NO;
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ID];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // 從緩存池取
 UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    cell.backgroundColor=[UIColor redColor];
    return cell;
}

1.3庐舟、補(bǔ)充:根據(jù)item的個數(shù)動態(tài)確定collectionview高度

      collectionView高度 = rows * itemWH

     1.確定item的個數(shù)
      NSInteger count = _squareItems.count;

     2.獲得collectionview的總行數(shù)
      NSInteger rows = (count - 1) / cols + 1;
        // Rows = (count - 1) / cols + 1,collectionview萬能公式計算總行數(shù)
  
      3.// 設(shè)置collectioView高度
       self.collectionView.frame=CGRectMake(0, 0, 375, rows*itemWH);

二、item寬度不相等

2.1、標(biāo)簽實現(xiàn)

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
   CGFloat linemargin = 15;
   CGFloat itemmargin = 10;
   CGFloat y = 50;
    NSArray *arr = @[@"測試",@"測試測試",@"ceshiceshiceshi",@"cccc",@"dddffkkkkf",@"2344",@"rrrrr",@"ffffffffffff",@"0000",@"lopp[[[eoeoeeoro"];
    CGRect lastFrame = CGRectZero;
 
    for (int i=0; i<10; i++) {
        UILabel *lable = [[UILabel alloc]init];
        lable.text = arr[i];
        lable.font = [UIFont systemFontOfSize:18];
        CGFloat width = [self getWidthWithText:arr[i] height:40 font:18];
        lable.backgroundColor = [UIColor redColor];
        [self.view addSubview:lable];
        if (i==0) {
            lable.text = arr[i];
            lable.frame = CGRectMake(0, y, width, 40);
        }else{
            CGFloat x = CGRectGetMaxX(lastFrame) + itemmargin;
            if (x+width>[UIScreen mainScreen].bounds.size.width) {
                x = 0;
                
                y =  CGRectGetMaxY(lastFrame)+linemargin;
            }
            
            lable.frame = CGRectMake(x, y, width, 40);
            
        }
        lastFrame = lable.frame;
    }
}

//根據(jù)高度度求寬度  text 計算的內(nèi)容  Height 計算的高度 font字體大小
-(CGFloat)getWidthWithText:(NSString *)text height:(CGFloat)height font:(CGFloat)font{
    
    CGRect rect = [text boundingRectWithSize:CGSizeMake(MAXFLOAT, height)
                                        options:NSStringDrawingUsesLineFragmentOrigin
                                     attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}
                                        context:nil];
    return rect.size.width;
}

2.2晃择、collectionFlowout布局

import UIKit
protocol CustomFlowLayoutDelgate:AnyObject{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
    
}
class CustomFlowLayout: UICollectionViewLayout{
    weak var delegate:CustomFlowLayoutDelgate?
    var attributes = [UICollectionViewLayoutAttributes]()
    var itemSpacing = 0.0
    var lineSpacing = 0.0
    var sectionSpacing = 0.0
    
    var rectHeight:CGFloat {
        get{
            return lastAttributes?.frame.maxY ?? 0
        }
    }
    private var lastAttributes:UICollectionViewLayoutAttributes?
    override var collectionViewContentSize: CGSize{
        return CGSize(width: 0, height: lastAttributes?.frame.maxY ?? 1000.0)
    }
    override func prepare(){
        attributes.removeAll()

        var y: CGFloat = 0
        var x:CGFloat = 0
        guard let numberOfSection = self.collectionView?.numberOfSections else { return }
        for i in 0 ..< numberOfSection {
            //創(chuàng)建頭部視圖布局屬性
            let attrheader = UICollectionViewLayoutAttributes.init(forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, with: IndexPath(item: 0, section: i))
            let size = self.delegate?.collectionView(self.collectionView!, layout: self, referenceSizeForHeaderInSection: i)
            if let lastAttr = self.lastAttributes{
                attrheader.frame = CGRectMake(0, lastAttr.frame.maxY + sectionSpacing, self.collectionView!.frame.width, size?.height ?? 0)
            }else{
                attrheader.frame = CGRectMake(0, 0, self.collectionView!.frame.width, 50)
            }
           
            self.attributes.append(attrheader)
            lastAttributes = attrheader
            let numberOfitem = self.collectionView!.numberOfItems(inSection: i)
            //y =  attrheader.frame.maxY
            for j in 0 ..< numberOfitem{
                let indexPath =  IndexPath(item: j, section: i)
                //創(chuàng)建cell視圖布局屬性
                let attr = UICollectionViewLayoutAttributes.init(forCellWith: indexPath)
                let size = self.delegate?.collectionView(self.collectionView!, layout: self, sizeForItemAt:indexPath)
                attr.frame.size.width = size!.width
                attr.frame.size.height = size!.height
                    if( lastAttributes?.representedElementKind == UICollectionView.elementKindSectionHeader){
                        x = 0
                        y =  lastAttributes?.frame.maxY ?? 0
                        attr.frame.origin.x = x
                        attr.frame.origin.y = y
                    }else{
                        x = (lastAttributes?.frame.maxX ?? 0) + self.itemSpacing
                        if x + attr.frame.width > self.collectionView!.bounds.width {
                            x = 0
                            y =  (lastAttributes?.frame.maxY ?? 0) + self.lineSpacing
                        }
                        
                        attr.frame.origin.x = x
                        attr.frame.origin.y = y
 
                    }
                    lastAttributes = attr
                    self.attributes.append(attr)
            }
        }
    }
    
    public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? // return an array
    {

        return self.attributes
        
    }
    
//    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
//        return nil
//    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市也物,隨后出現(xiàn)的幾起案子宫屠,更是在濱河造成了極大的恐慌,老刑警劉巖滑蚯,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪蹂,死亡現(xiàn)場離奇詭異,居然都是意外死亡告材,警方通過查閱死者的電腦和手機(jī)坤次,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斥赋,“玉大人缰猴,你說我怎么就攤上這事“探#” “怎么了滑绒?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵闷堡,是天一觀的道長。 經(jīng)常有香客問我疑故,道長杠览,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任纵势,我火速辦了婚禮倦零,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吨悍。我一直安慰自己扫茅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布育瓜。 她就那樣靜靜地躺著葫隙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪躏仇。 梳的紋絲不亂的頭發(fā)上恋脚,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音焰手,去河邊找鬼糟描。 笑死,一個胖子當(dāng)著我的面吹牛书妻,可吹牛的內(nèi)容都是我干的船响。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼躲履,長吁一口氣:“原來是場噩夢啊……” “哼见间!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起工猜,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤米诉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后篷帅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體史侣,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年魏身,在試婚紗的時候發(fā)現(xiàn)自己被綠了惊橱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡叠骑,死狀恐怖李皇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤掉房,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布茧跋,位于F島的核電站,受9級特大地震影響卓囚,放射性物質(zhì)發(fā)生泄漏瘾杭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一哪亿、第九天 我趴在偏房一處隱蔽的房頂上張望粥烁。 院中可真熱鬧,春花似錦蝇棉、人聲如沸讨阻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钝吮。三九已至,卻和暖如春板辽,著一層夾襖步出監(jiān)牢的瞬間奇瘦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工劲弦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耳标,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓邑跪,卻偏偏與公主長得像次坡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子呀袱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一個簡單的九宮格布局 思路 利用控件的索引index計算出控件所在的行號和列號 利用列號計算控件的x值 利用行號計...
    皆為序幕_閱讀 3,731評論 0 3
  • iOS masonry九宮格 單行 多行布局 Masonry是個好東西贸毕,在當(dāng)前尺寸各異的iOS開發(fā)適配中發(fā)揮著至關(guān)...
    壞壞De學(xué)長閱讀 3,167評論 0 8
  • 寬度:定義將要添加的這些控件的寬度。 高度:定義將要添加的這些控件的高度夜赵。 列數(shù):你想讓這些控件排成幾列。
    BabyNeedCare閱讀 383評論 0 0
  • 久違的晴天乡革,家長會寇僧。 家長大會開好到教室時,離放學(xué)已經(jīng)沒多少時間了沸版。班主任說已經(jīng)安排了三個家長分享經(jīng)驗嘁傀。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,520評論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友视粮。感恩相遇细办!感恩不離不棄。 中午開了第一次的黨會,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,562評論 0 11