2013-03-28 11:14:38 k214k 阅读数 3625

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    

    return 44;

}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

    return 1;

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    

    if ([m_showArray count]%4)

    {

        return [m_showArray count]/4+1;

    }

    else

    {

        return [m_showArray count]/4;

    }

    

}


-(void)selectBtItem:(id)sender

{

    

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *strIndicator = @"CellId";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strIndicator];

    for (UIView *view in cell.subviews)

    {

        if ([view isKindOfClass:[CustomButton class]])

        {

            [view removeFromSuperview];

        }

        

    }

    if (!cell)

    {

        cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strIndicator]autorelease];

        cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:cell.frame] autorelease];

        cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];

        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    }

    

    for (int i = 0;i < 4; ++i)

    {

        if (([m_showArray count]%4)&&(indexPath.row == [m_showArray count]/4)&&([m_showArray count]%4 == i))

        {//不能被4整除的余数处理,

            break;

        }

        CustomButton* tempBt = [[CustomButton alloc] initWithFrame:CGRectMake(10+i*80, 10, 60, 20)];

        tempBt.tag = 2000+i;

        tempBt.m_tag = m_index;

        

        [tempBt setTitle:tempCity.cityName forState:UIControlStateNormal];

        [tempBt setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

        tempBt.backgroundColor = [UIColor clearColor];

        [tempBt addTarget:self action:@selector(selectBtItem:) forControlEvents:UIControlEventTouchUpInside];

        [cell addSubview:tempBt];

        [tempBt release];

        m_index = (m_index + 1)%[m_showArray count];

    }

    return cell;

}

2017-02-14 16:44:29 ZY_Zain 阅读数 8528

智勇博客:

业余时间有空分享一下个人封装的一个图片浏览器。代码已经封装好,并且提供了一个config.h配置文件 需要更改的一些参数 直接在里面更改即可,无需深入代码研究,修改。有兴趣学习的朋友也可以深入了解一下代码。

本第三方最多支持9张图片的展示,支持GIF,支持长图,支持横屏展示大图,会按9宫格进行布局,可以自定义整个控件的宽度,高度是根据图片的数量自适应的。 当传进去的图片数量大于9张,自动会取前9张图片进行展示,当图片只有4张和1张时会有单独的布局 详细看下面的图片。



点击图片时 会有动画效果 放大至全屏查看 然后双击放大某个区域 再次双击缩小  缩放 长按保存图片 单击退出大图模式  等手势都在内部做好了处理    外界不需要管。  放大图片后 旋转屏幕 也在内部单独适配了,你的程序不需要适配横屏,在大图模式下 也能自动适配横屏查看图片。

详细看下面的GIF图片展示   至于横屏展示图片并没有做GIF,大家可以下载Demo来运行起来,里面我准备了一张gif的URL  可以直接运行Demo起来看效果。





如果你感觉此第三方对你有帮助,请点赞和移步到gitHub给个星!感谢!  你的点赞是我更新更多第三方的动力!

gitHub地址


2015-07-09 11:52:55 u014493178 阅读数 529

实现效果


1.开发前的思路

1> mainBundle中加载Plist

2> 按照plist中的数据数量先确定各个appView的大小和位置

3> 使用代码创建appView中的子控件,并显示内容

代码一

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        _appInfo = [NSArray arrayWithContentsOfFile:path];
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
        
        // 读取数组中的字典
        NSDictionary *dict = self.appInfo[i];
        
        UIView *appView =  [[UIView alloc] init];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];
        //设置图标
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = CGRectMake(0, 0, viewW, 50);
        //设置图片
        imageView.image = [UIImage imageNamed:dict[@"icon"]];
        //按照比例显示图像
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [appView addSubview:imageView];
        //设置lable
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
        //设置文字内容
        label.text = dict[@"name"];
        //设置文字大小
        label.font = [UIFont systemFontOfSize:12];
        //设置文字居中对齐
        label.textAlignment = NSTextAlignmentCenter;
        [appView addSubview:label];
        //设置button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(15, 70, viewW - 30, 20);
        //设置文字
        /**
         不能使用下载的方法
         *   button.titleLabel.text = @"下载";
         应该使用下面的方法
          [button setTitle:@"下载" forState:UIControlStateNormal];
         */
       
        [button setTitle:@"下载" forState:UIControlStateNormal];
        //设置文字大小
        //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        //设置按钮图片
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
        [appView addSubview:button];
        button.tag = i;
        [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
    
    }
}

- (void)downloadClick:(UIButton *)button
{
    NSLog(@" %ld ",(long)button.tag);
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    NSDictionary *dict = self.appInfo[button.tag];
    lable.text = [NSString stringWithFormat:@"下载%@完成",dict[@"name"]];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
//    [UIView beginAnimations:nil context:nil];
//    [UIView setAnimationDuration:1.0];
//    lable.alpha = 1.0;
//    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.view addSubview:lable];
    
}

关于上面方法的总结

2. 关于九宫格布局的计算方法

========================================

关于如何计算界面的九宫格布局,其实可以有若干种方法,不必死记课堂的代码,

要能够顺利计算出每一个小格子准确的坐标,建议:

1先创建若干小的视图

2找到自己理解比较容易的计算方法

3编写循环创建九宫格布局


要求:能够公用的常量尽量给抽取出来,以便增加九宫格布局的灵活性,尽量保证做到:

1> 根据要显示的数据自动调整小格子的位置和数量

2> 一旦调整了要显示的列数,仅需要修改少量的数值即可做到


3. 关于UIButton的一些补充

========================================

3.1 按钮的类型

iOS的控件中,只有UIButton提供了类方法,可以在实例化按钮时指定按钮的不同类型。


UIButtonTypeCustom[[UIButton alloc] init]是等价的


3.2 修改按钮字体


UIButton中定义有两个readonly的属性:

1> titleLabel

2> imageView

@propertyreadonly表示不允许修改这两个属性的指针地址,但是可以修改其属性


注意:由于按钮的字体大小是所有状态共用的,因此可以通过

button.titleLabel.font= [UIFont systemFontOfSize:14.0];

修改按钮标签文本的字体大小


但是不能使用以下代码设置按钮标签的文本内容

button.titleLabel.text = @"下载";


因为按钮标签的文本内容是跟按钮的状态向关的


4. 块动画

========================================

4.1 首尾式动画


如果只是修改控件的属性,使用首尾式动画还是比较方便的,但是如果需要在动画完成后做后续处理,就不是那么方便了


[UIView beginAnimations:nil context:nil];

[UIView setAnimationDuration:1.0];

// 修改属性的动画代码

// ......

[UIView commitAnimations];


4.2 块动画


块动画相对来说比较灵活,尤为重要的是能够将动画相关的代码编写在一起,便于代码的阅读和理解


[UIView animateWithDuration:2.0 animations:^{

    // 修改控件属性动画

    label.alpha = 0.0;

} completion:^(BOOL finished) {

    // 删除控件

    [label removeFromSuperview];

}];

代码优化一

    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            //1. 遍历数组,将数组中的字典依次转换成SDApplist对象,添加到一个临时数组
            //2. self.SDApplist = 临时数组
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [[SDApplist alloc] init];
                appInfo.name = dict[@"name"];
                appInfo.icon = dict[@"icon"];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            UIView *appView =  [[UIView alloc] init];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //设置图标
            UIImageView *imageView = [[UIImageView alloc] init];
            imageView.frame = CGRectMake(0, 0, viewW, 50);
            //设置图片
            imageView.image = [UIImage imageNamed:appInfo.icon];
            //按照比例显示图像
            imageView.contentMode = UIViewContentModeScaleAspectFit;
            [appView addSubview:imageView];
            //设置lable
            UILabel *label = [[UILabel alloc] init];
            label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
            //设置文字内容
            label.text = appInfo.name;
            //设置文字大小
            label.font = [UIFont systemFontOfSize:12];
            //设置文字居中对齐
            label.textAlignment = NSTextAlignmentCenter;
            [appView addSubview:label];
            //设置button
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            button.frame = CGRectMake(15, 70, viewW - 30, 20);
            //设置文字
            /**
             不能使用下载的方法
             *   button.titleLabel.text = @"下载";
             应该使用下面的方法
             [button setTitle:@"下载" forState:UIControlStateNormal];
             */
            
            [button setTitle:@"下载" forState:UIControlStateNormal];
            //设置文字大小
            //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
            button.titleLabel.font = [UIFont systemFontOfSize:12];
            //设置按钮图片
            [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
            [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
            [appView addSubview:button];
            button.tag = i;
            [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }

SDApplist

//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
@end



代码优化2

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"
#include "SDApplist.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
            [arrayM addObject:appInfo];
        }
        _appInfo = arrayM;
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
        
        // 读取数组中的字典
        SDApplist *appInfo = self.appInfo[i];
        
        UIView *appView =  [[UIView alloc] init];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];
        //设置图标
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = CGRectMake(0, 0, viewW, 50);
        //设置图片
//        imageView.image = appInfo.image;
        imageView.image = appInfo.image;
        //按照比例显示图像
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [appView addSubview:imageView];
        //设置lable
        UILabel *label = [[UILabel alloc] init];
        label.frame = CGRectMake(0, imageView.bounds.size.height, viewW, 20);
        //设置文字内容
        label.text = appInfo.name;
        //设置文字大小
        label.font = [UIFont systemFontOfSize:12];
        //设置文字居中对齐
        label.textAlignment = NSTextAlignmentCenter;
        [appView addSubview:label];
        //设置button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(15, 70, viewW - 30, 20);
        //设置文字
        /**
         不能使用下载的方法
         *   button.titleLabel.text = @"下载";
         应该使用下面的方法
          [button setTitle:@"下载" forState:UIControlStateNormal];
         */
       
        [button setTitle:@"下载" forState:UIControlStateNormal];
        //设置文字大小
        //@property中readonly表示不允许修改对象的指针地址,但是可以修改对象的属性
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        //设置按钮图片
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
        [button setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
        [appView addSubview:button];
        button.tag = i;
        [button addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
    
    }
}

- (void)downloadClick:(UIButton *)button
{
    NSLog(@" %ld ",(long)button.tag);
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    SDApplist *appInfo = self.appInfo[button.tag];
    lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
//    [UIView beginAnimations:nil context:nil];
//    [UIView setAnimationDuration:1.0];
//    lable.alpha = 1.0;
//    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.view addSubview:lable];
    
}
@end

SDApplist.h

//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end


SDApplist.m

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

5. 字典转模型

========================================

5.1 字典转模型的好处:

1> 降低代码的耦合度

2> 所有字典转模型部分的代码统一集中在一处处理,降低代码出错的几率

3> 在程序中直接使用模型的属性操作,提高编码效率


模型应该提供一个可以传入字典参数的构造方法

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)xxxWithDict:(NSDictionary *)dict;


5.2 instancetype &id

1> instancetype在类型表示上,跟id一样,可以表示任何对象类型

2> instancetype只能用在返回值类型上,不能像id一样用在参数类型上

3> instancetypeid多一个好处:编译器会检测instancetype的真实类型


5.3 在模型中添加readonly属性

// 定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量

// 而如果是readonly属性,则只会生成getter方法,同时没有成员变量

@property (nonatomic,strong,readonly) UIImage *image;


@interface LFAppInfo()

{

    UIImage *_imageABC;

}

- (UIImage *)image

{

    if (!_imageABC) {

        _imageABC = [UIImage imageNamed:self.icon];

    }

    return _imageABC;

}

在模型中合理地使用只读属性,可以进一步降低代码的耦合度。


5.4 使用数据模型的好处:

*** 调用方不用关心模型内部的任何处理细节!


代码优化三

    //
    //  ViewController.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/3.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"
    
    @interface ViewController ()
    /**
     *  数据plist
     */
    @property (nonatomic,strong) NSArray *appInfo;
    @end
    
    @implementation ViewController
    
    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
            NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];
            NSLog(@"%@",array);
            SDAPPlnfoView *appView = [array firstObject];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //1、设置图片
            appView.iconImage.image = appInfo.image;
            //2、设置文本
            appView.nameLable.text = appInfo.name;
            //3、设置button的tag
            appView.dowBtn.tag = i;
            //4、设置button的监听方法
            [appView.dowBtn addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }
}


//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

//
 //  SDAPPlnfoView.h
 //  01-应用程序管理
 //
 //  Created by sunda on 15/7/13.
 //  Copyright (c) 2015年 sunda. All rights reserved.
 //
 
 #import <UIKit/UIKit.h>

 @interface SDAPPlnfoView : UIView
 
 
//  下载按钮
@property (weak, nonatomic) IBOutlet UIButton *dowBtn;
 

//图片
@property (strong, nonatomic) IBOutlet UIImageView *iconImage;

//文本
@property (strong, nonatomic) IBOutlet UILabel *nameLable;

代码优化四

    //
    //  ViewController.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/3.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"
    
    @interface ViewController ()
    /**
     *  数据plist
     */
    @property (nonatomic,strong) NSArray *appInfo;
    @end
    
    @implementation ViewController
    
    - (NSArray *)appInfo
    {
        if (_appInfo == nil) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
            NSArray *array = [NSArray arrayWithContentsOfFile:path];
            //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
            NSMutableArray *arrayM = [NSMutableArray array];
            for (NSDictionary *dict in array) {
                SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
                [arrayM addObject:appInfo];
            }
            _appInfo = arrayM;
        }
        return _appInfo;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
#define totaCol 3
#define padding 20
        
        CGFloat viewW = 80;
        CGFloat viewH = 90;
        CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
        CGFloat marginY = 20;
        
        
        for (int i = 0; i < self.appInfo.count; i++) {
            int  row = i / totaCol;
            int col = i % totaCol;
            CGFloat x = marginX + (viewW + marginX) * col;
            CGFloat y = marginY + (viewH + marginY) * row + padding;
            
            // 读取数组中的字典
            SDApplist *appInfo = self.appInfo[i];
            
            //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
            NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];
            NSLog(@"%@",array);
            SDAPPlnfoView *appView = [array firstObject];
            appView.frame = CGRectMake(x, y, viewW, viewH);
            [self.view addSubview:appView];
            //读取数组中的AppInfo
            appView.appInfo = self.appInfo[i];
            
            
            
            appView.dowBtn.tag = i;
            //4、设置button的监听方法
            [appView.dowBtn addTarget:self action:@selector(downloadClick:) forControlEvents:UIControlEventTouchUpInside];
            
        }
    }
    
    - (void)downloadClick:(UIButton *)button
    {
        NSLog(@" %ld ",(long)button.tag);
        //提示用户已经完成
        UILabel *lable = [[UILabel alloc] init];
        lable.frame = CGRectMake(80, self.view.bounds.size.height - 100, 200, 40);
        lable.textAlignment = NSTextAlignmentCenter;
        lable.backgroundColor = [UIColor lightGrayColor];
        SDApplist *appInfo = self.appInfo[button.tag];
        lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
        lable.alpha = 1.0;
        lable.font = [UIFont systemFontOfSize:13];
        
        //动画效果
        //动画效果完成之后,将lable从视图中删除
        //首尾式动画,只能做动画,要处理完成后的操作不方便
        //    [UIView beginAnimations:nil context:nil];
        //    [UIView setAnimationDuration:1.0];
        //    lable.alpha = 1.0;
        //    [UIView commitAnimations];
        
        /**
         *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
         *  在ios中基本使用首尾式动画
         */
        [UIView animateWithDuration:1.0 animations:^{
            lable.alpha = 0.0;
        } completion:^(BOOL finished) {
            //删除lable
            [lable removeFromSuperview];
        }];
        
        button.enabled = NO;
        
        [self.view addSubview:lable];
        
    }
}
//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end


//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

  SDAPPlnfoView.h
  01-应用程序管理

  Created by sunda on 15/7/13.
  Copyright (c) 2015年 sunda. All rights reserved.


#import <UIKit/UIKit.h>
@class SDApplist;
@interface SDAPPlnfoView : UIView


//下载按钮

@property (weak, nonatomic) IBOutlet UIButton *dowBtn;

@property (strong, nonatomic) SDApplist *appInfo;
@end

    //
    //  SDAPPlnfoView.m
    //  01-应用程序管理
    //
    //  Created by sunda on 15/7/13.
    //  Copyright (c) 2015年 sunda. All rights reserved.
    //
    
#import "SDAPPlnfoView.h"
#import "SDApplist.h"
    @interface SDAPPlnfoView()
    /**
     *  图片
     */
    @property (strong, nonatomic) IBOutlet UIImageView *iconImage;
    /**
     *  文本
     */
    @property (strong, nonatomic) IBOutlet UILabel *nameLable;
    
    @end
    
    @implementation SDAPPlnfoView
    
    - (void)setAppInfo:(SDApplist *)appInfo
    {
        //在Settrt中一定要用成员变量记录参数
        _appInfo = appInfo;
        self.iconImage.image = appInfo.image;
        self.nameLable.text = appInfo.name;
    }

最后一次优化

//
//  ViewController.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/3.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "ViewController.h"
#include "SDApplist.h"
#include "SDAPPlnfoView.h"

@interface ViewController ()
/**
 *  数据plist
 */
@property (nonatomic,strong) NSArray *appInfo;
@end

@implementation ViewController

- (NSArray *)appInfo
{
    if (_appInfo == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        //将数值转换成模型,意味着self.applist中存储的是SDAppLIst
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in array) {
            SDApplist *appInfo = [SDApplist SDApplistWithDict:dict];
            [arrayM addObject:appInfo];
        }
        _appInfo = arrayM;
    }
    return _appInfo;
}

- (void)viewDidLoad {
    [super viewDidLoad];
#define totaCol 3
#define padding 20
    
    CGFloat viewW = 80;
    CGFloat viewH = 90;
    CGFloat marginX = (self.view.bounds.size.width - totaCol *viewW) / (totaCol + 1);
    CGFloat marginY = 20;

    
    for (int i = 0; i < self.appInfo.count; i++) {
        int  row = i / totaCol;
        int col = i % totaCol;
        CGFloat x = marginX + (viewW + marginX) * col;
        CGFloat y = marginY + (viewH + marginY) * row + padding;
    
    
        SDAPPlnfoView *appView = [SDAPPlnfoView appInfoViewWithAppList:self.appInfo[i]];
        appView.frame = CGRectMake(x, y, viewW, viewH);
        [self.view addSubview:appView];

    }
}
@end


//
//  SDApplist.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface SDApplist : NSObject
/**
 *  名字
 */
@property (nonatomic, strong)NSString *name;
/**
 *  图片
 */
@property (nonatomic, strong)NSString *icon;
/**
 *  自定义属性时,会生成getter&setter方法,还会生成一个带下划线的成员变量
 *  如果是readonly属性,只会生成getter方法,同事没有成员变量
 */
@property (nonatomic,readonly ,strong)UIImage *image;

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict;

@end

//
//  SDApplist.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/9.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDApplist.h"
#import <UIKit/UIKit.h>

@interface SDApplist()
{
    UIImage *_imageA;
}

@end

@implementation SDApplist


- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        self.name = dict[@"name"];
        self.icon = dict[@"icon"];
    }
    return self;
}

- (UIImage *)image
{
    if (_imageA == NULL) {
        _imageA = [UIImage imageNamed:self.icon];
    }
    return _imageA;
}

+ (instancetype)SDApplistWithDict:(NSDictionary *)dict
{
    return [[self alloc] initWithDict:dict];
}


@end

//
//  SDAPPlnfoView.h
//  01-应用程序管理
//
//  Created by sunda on 15/7/13.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import <UIKit/UIKit.h>
@class SDApplist;
@interface SDAPPlnfoView : UIView


+(instancetype)appInfoView;
+(instancetype)appInfoViewWithAppList:(SDApplist *)applist;

@end
//
//  SDAPPlnfoView.m
//  01-应用程序管理
//
//  Created by sunda on 15/7/13.
//  Copyright (c) 2015年 sunda. All rights reserved.
//

#import "SDAPPlnfoView.h"
#import "SDApplist.h"
@interface SDAPPlnfoView()
/**
 *  图片
 */
@property (strong, nonatomic) IBOutlet UIImageView *iconImage;
/**
 *  文本
 */
@property (strong, nonatomic) IBOutlet UILabel *nameLable;

/**
 *  下载按钮
 */
@property (weak, nonatomic) IBOutlet UIButton *dowBtn;

@property (strong, nonatomic) SDApplist *appInfo;

@end

@implementation SDAPPlnfoView

- (void)setAppInfo:(SDApplist *)appInfo
{
    //在Settrt中一定要用成员变量记录参数
    _appInfo = appInfo;
    self.iconImage.image = appInfo.image;
    self.nameLable.text = appInfo.name;
}
- (IBAction)downloadClick:(UIButton *)button{
    //提示用户已经完成
    UILabel *lable = [[UILabel alloc] init];
    lable.frame = CGRectMake(80, 500 , 200, 40);
    lable.textAlignment = NSTextAlignmentCenter;
    lable.backgroundColor = [UIColor lightGrayColor];
    
    SDApplist *appInfo = self.appInfo;
    lable.text = [NSString stringWithFormat:@"下载%@完成",appInfo.name];
    lable.alpha = 1.0;
    lable.font = [UIFont systemFontOfSize:13];
    
    //动画效果
    //动画效果完成之后,将lable从视图中删除
    //首尾式动画,只能做动画,要处理完成后的操作不方便
    //    [UIView beginAnimations:nil context:nil];
    //    [UIView setAnimationDuration:1.0];
    //    lable.alpha = 1.0;
    //    [UIView commitAnimations];
    
    /**
     *  block 动画比首尾式动画简单,而且能够控制动画结束后的操作
     *  在ios中基本使用首尾式动画
     */
    [UIView animateWithDuration:1.0 animations:^{
        lable.alpha = 0.0;
    } completion:^(BOOL finished) {
        //删除lable
        [lable removeFromSuperview];
    }];
    
    button.enabled = NO;
    
    [self.superview addSubview:lable];

}
+ (instancetype)appInfoView
{
    //loadNibNamed 会将名为AppInfoView中定义的使用视图全部加载出来,并且按照XIB中自定义的顺序,返回一个视图的数组
        NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"APPInfo" owner:nil options:nil];

        return [array firstObject];
}
+ (instancetype)appInfoViewWithAppList:(SDApplist *)applist
{
    SDAPPlnfoView *view = [self appInfoView];
    view.appInfo = applist;
    return view;
}



@end


6. XIB

========================================

Xib文件可以用来描述某一块局部的UI界面


XIB & Storyboard

相同点:

1都用来描述软件界面

2都用Interface Builder工具来编辑

不同点

1>  Xib是轻量级的,用来描述局部的UI界面

2>  Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系


7. View的封装思路

========================================

1如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心

2外界可以传入对应的模型数据给viewview拿到模型数据后给内部的子控件设置对应的数据



2019-01-09 01:12:34 weixin_34032827 阅读数 108

文章中贴出的XML代码你可以直接从git下载并且运行查看效果,git下载地址

这篇带给大家的是对闲鱼app搜索结果页面的布局分析。这类布局的特点是瀑布流宫格布局,也可能设计多种不同的Cell(模板),先上图,如下:

从图片中可以看出如下几个点。

  1. 宫格布局(严格来说可以说是瀑布流布局)。
  2. 每行显示两个Cell
  3. 共有三种不同的Cell
  4. 有些Cell会横跨两列。比如细选那个Cell

上面的是大体布局。下面分别分析不同Cell的布局分析

Cell-1(商品布局)










商品信息Cell整体属于自上而下布局。

  1. 顶部的是商品的图片,并且是按照1:1比例显示。
  2. 商品名称。并且最多显示一行
  3. 商品价格等信息
  4. 用户和位置等信息。并且信用的信息显示在右边,头像的右下角还有一个绿色小点。
  5. 包邮、全新等信息。

下面一一进行分析。

  1. 商品图片的显示。

     <!-- 商品图片,并且按照1:1的比例来显示 -->
     <ratio-panel ratio="1" background-color="gray">
         <image url="{{cover}}" />
     </ratio-panel>
    复制代码

    使用ratio-panel提供1:1比例的布局。

  2. 商品名称显示。

    <!-- 商品名称 -->
    <lable text="{{name}}" font-size="14" font-color="444444" lines="1" />
    复制代码
  3. 商品价格等信息。

    价格信息本来是可以使用lable的富文本方式来显示的,但是lable的富文本的内容是靠底部显示的。但是这里需要垂直居中来显示。那么只有使用stack-panel才能满足要求了

    <!-- 水平布局,并且垂直方向居中显示 -->
    <stack-panel is-horizon="true" align-items="2">
        <!-- 商品价格 -->
        <lable text="¥" font-color="FB2A35" font-size="12" />
        <lable text="{{price}}" font-color="FB2A35" font-size="16" />
        <!-- 想要数量 -->
        <lable text="{{want+'人想要'}}" font-color="gray" font-size="11" space-before="5" />
    </stack-panel>
    复制代码

    stack-panelalign-items属性是关键,决定了垂直方向是居中显示的。

  1. 用户和位置等信息。并且信用的信息显示在右边,头像的右下角还有一个绿色小点。
    <!-- 用户信息 水平布局,并且垂直方向居中布局-->
    <stack-panel data-path="user" is-horizon="true" space="5" align-items="2">
        <!-- 头像 -->
        <dock-panel size="25" corner-radius="5" clips-bounds="true">
            <image background-color="gray" url="{{headIcon}}" />
            <!-- 右下角显示绿色小点 -->
            <panel size="8" background-color="49C856" dock-panel.horizal="2" dock-panel.vertical="2" border-color="white" border-width="2" corner-radius="4" />
        </dock-panel>
        <!-- 用户位置信息 -->
        <lable text="{{location.name}}" font-color="gray" font-size="10" />
        <!-- 信用显示在右边 -->
        <lable text="芝麻信用|极好" font-color="2EC5BE" font-size="10" flex-grow="1" text-align="2" />
    </stack-panel>
    复制代码
    1. 信用信息显示在右边。关键代码是flex-grow="1" text-align="2"。这段代码的意思是该lable占用右边的所有剩余空间,并且文本靠右显示。
    2. 用户右下角的绿色小点。关键代码是dock-panel.horizal="2" dock-panel.vertical="2"

  1. 包邮、全新等信息

    包邮、全新等信息的显示比较特殊,显示在顶部图片的左下角,并且在x和y方向上分别都偏移了一段距离。GIC并没有提供可以偏移的布局面板,但是提供了transforms功能。因此这里就依靠transforms来实现了。

    另外,信息是显示图片上,并且显示在左下角。那么只能采用dock-panel布局了。并且和图片存在于同一个dock-panel中。

    <!-- 商品图片,并且按照1:1的比例来显示 -->
    <ratio-panel ratio="1" background-color="gray">
        <dock-panel>
            <!-- 图片 -->
            <image url="{{cover}}" />
            <!-- 全新和包邮图标 -->
            <stack-panel dock-panel.horizal="0" dock-panel.vertical="2" space="2" is-horizon="true">
                <transforms>
                    <!-- x和y方向偏移 -->
                    <translate x="10" y="8" />
                </transforms>
                <!-- 全新图标 -->
                <if condition="{{ isNew }}">
                    <dock-panel background-color="FB2A35" size="30 16" corner-radius="3">
                        <lable text="全新" font-size="10" font-color="white" />
                    </dock-panel>
                </if>
                <!-- 包邮图标 -->
                <if condition="{{ baoyou }}">
                    <dock-panel background-color="2F9AFE" size="30 16" corner-radius="3">
                        <lable text="包邮" font-size="10" font-color="white" />
                    </dock-panel>
                </if>
            </stack-panel>
        </dock-panel>
    </ratio-panel>
    复制代码

    全新包邮的图标并不是每个cell都有的,因此使用if指令来显示。

Cell-2(标签)










上面的cell的布局区别于商品信息cell。这个cell的布局难点在于三个头像的布局。这里面使用panel来布局,并且使用postion来实现在水平方向的偏移布局。

<panel>
    <for data-path="users">
        <image size="20" url="{{headIcon}}" corner-radius="10" position="{{ 13*$index+' 0' }}" />
    </for>
</panel>
复制代码

可以看到,每个image的大小为20,设置了10的圆角,这样就成为一个圆形头像。然后每个图片在x方向进行偏移13*$index。这样就形成一个部分重叠交集的布局效果了。

Cell-3(筛选)









这个cell的布局就简单了。上面是`title`,下面是一个每行4列的`宫格布局`面板。
  1. title的布局。

    左右两边分别有一根线,中间是一个lable

    <stack-panel space-before="20" is-horizon="true" align-items="2" space="10" justify-content="1">
        <panel size="30 1" background-color="light-gray" corner-radius="0.5" />
        <lable text="细选" font-size="16" font-color="111111" />
        <panel size="30 1" background-color="light-gray" corner-radius="0.5" />
    </stack-panel>
    复制代码
  2. 宫格布局

    <grid-panel columns="4" column-spacing="15" space-before="10" row-spacing="15" space-after="20">
        <for>
            <dock-panel background-color="E1E3E9" height="35" corner-radius="5">
                <lable text="{{}}" font-size="14" font-color="333333" />
            </dock-panel>
        </for>
    </grid-panel>
    复制代码

整体布局

上面列出了三种cell的布局方式。每个cell对应一个template。并且使用collection-view来实现瀑布流布局。

另外,Cell3(筛选)的Cell需要跨两列显示。只需要设置collection-viewcolumn-span附加属性即可。

<collection-view columns="2" row-spacing="10" content-inset="10" background-color="F0F2F8">
    <section>
        <for data-path="items">
            <!-- 使用数据绑定的方式来确定每个cell对应的跨列数 -->
            <list-item corner-radius="5" background-color="white" collection-view.column-span="{{ (type==3?3:1) }}">
                <!-- 使用数据绑定的方式动态选择不同的模板显示 -->
                <template-ref t-name="{{ this.typeToTemplateName(type) }}" />
            </list-item>
        </for>
    </section>
</collection-view>
复制代码

以上的布局代码就是整个闲鱼app搜索结果界面的布局代码。总共才100多行xml代码,比起传统的采用UITableViewCell的开发方式,不仅在开发效率还是代码可读性上面都有极大的优势。

另外,你可以在运行demo的时候旋转屏幕,你会发现所有的布局都会自动重新布局。而这个过程你甚至连一行代码都不用写。

2014-11-24 22:04:00 daxiguan0304 阅读数 5
需求
1.以N宫格的形式展示应用信息
2.APP信息包括图标、名字、下载按钮
3.使用尽可能少的代码,从plist读取app信息,计算每个app图标的位置尺寸信息
 
Image
 
A.思路
1.UI布局:N宫格
2.事件监听
3.动态添加 (by plist)
4.整体封装,组合每个应用信息,使用View的层级包装帮助布局
 
B.实现 (使用纯代码方式)
 
  1 //
  2 //  ViewController.m
  3 //  01-应用管理
  4 //
  5 //  Created by hellovoidworld on 14/11/24.
  6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
  7 //
  8 
  9 #import "ViewController.h"
 10 
 11 #define APP_WIDTH 85
 12 #define APP_HEIGHT 90
 13 #define MARGIN_HEAD 20
 14 #define ICON_WIDTH 50
 15 #define ICON_HEIGHT 50
 16 #define NAME_WIDTH APP_WIDTH
 17 #define NAME_HEIGHT 20
 18 #define DOWNLOAD_WIDTH (APP_WIDTH - 20)
 19 #define DOWNLOAD_HEIGHT 20
 20 
 21 @interface ViewController ()
 22 
 23 /** 存放应用信息 */
 24 @property(nonatomic, strong) NSArray *apps; // 应用列表
 25 
 26 @end
 27 
 28 @implementation ViewController
 29 
 30 - (void)viewDidLoad {
 31     [super viewDidLoad];
 32     // Do any additional setup after loading the view, typically from a nib.
 33    
 34     [self loadApps];
 35 }
 36 
 37 - (void)didReceiveMemoryWarning {
 38     [super didReceiveMemoryWarning];
 39     // Dispose of any resources that can be recreated.
 40 }
 41 
 42 #pragma mark 取得应用列表
 43 - (NSArray *) apps {
 44     if (nil == _apps) {
 45         NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
 46         _apps = [NSArray arrayWithContentsOfFile:path];
 47     }
 48 
 49     return _apps;
 50 }
 51 
 52 #pragma mark 加载全部应用列表
 53 - (void) loadApps {
 54     int appColumnCount = [self appColumnCount];
 55     int appRowCount = [self appRowCount];
 56    
 57     CGFloat marginX = (self.view.frame.size.width - APP_WIDTH * appColumnCount) / (appColumnCount + 1);
 58     CGFloat marginY = (self.view.frame.size.height - APP_HEIGHT * appRowCount) / (appRowCount + 1) + MARGIN_HEAD;
 59    
 60     int column = 0;
 61     int row = 0;
 62     for (int index=0; index<self.apps.count; index++) {
 63         NSDictionary *appData = self.apps[index];
 64        
 65         // 每个app信息
 66         UIView *appView = [[UIView alloc] init];
 67        
 68         CGFloat appX = marginX + column * (marginX + APP_WIDTH);
 69         CGFloat appY = marginY + row * (marginY + APP_HEIGHT);
 70        
 71         appView.frame = CGRectMake(appX, appY, APP_WIDTH, APP_HEIGHT);
 72        
 73         // 1.设置APP图片
 74         UIImageView *iconView = [[UIImageView alloc] init];
 75        
 76         CGFloat iconMarginX = (appView.frame.size.width - ICON_WIDTH) / 2;
 77         CGFloat iconMarginY = 0;
 78         iconView.frame = CGRectMake(iconMarginX, iconMarginY, ICON_WIDTH, ICON_HEIGHT);
 79        
 80         iconView.image = [UIImage imageNamed:appData[@"icon"]];
 81         [appView addSubview:iconView];
 82        
 83         // 2.设置APP名字
 84         UILabel  *nameLabel = [[UILabel alloc] init];
 85         nameLabel.text = appData[@"name"];
 86         CGFloat nameMarginX = (appView.frame.size.width - NAME_WIDTH) / 2;
 87         CGFloat nameMarginY = iconMarginY + ICON_HEIGHT;
 88         nameLabel.frame = CGRectMake(nameMarginX, nameMarginY, NAME_WIDTH, NAME_HEIGHT);
 89         [nameLabel setFont:[UIFont systemFontOfSize:16]];
 90         [nameLabel setTextAlignment:NSTextAlignmentCenter];
 91         [appView addSubview:nameLabel];
 92        
 93         // 3.设置下载按钮
 94         UIButton *downloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
 95         CGFloat downloadMarginX = (appView.frame.size.width - DOWNLOAD_WIDTH) / 2;
 96         CGFloat downloadMarginY = nameMarginY + NAME_HEIGHT;
 97         downloadButton.frame = CGRectMake(downloadMarginX, downloadMarginY, DOWNLOAD_WIDTH, DOWNLOAD_HEIGHT);
 98        
 99         UIImage *downloadNormalImage = [UIImage imageNamed:@"buttongreen"];
100         [downloadButton setBackgroundImage:downloadNormalImage forState:UIControlStateNormal];
101        
102         UIImage *downloadHighlightedImage = [UIImage imageNamed:@"buttongreen_highlighted"];
103         [downloadButton setBackgroundImage:downloadHighlightedImage forState:UIControlStateHighlighted];
104        
105         [downloadButton setTitle:@"下载" forState:UIControlStateNormal];
106        
107         // 不要直接取出titleLabel属性进行操作,因为这样就不能为全部状态进行设置
108         [downloadButton.titleLabel setFont:[UIFont systemFontOfSize:13]];
109        
110         [appView addSubview:downloadButton];
111        
112        
113         [self.view addSubview:appView];
114        
115         column++;
116         if (column == appColumnCount) {
117             column = 0;
118             row++;
119         }
120     }
121 }
122 
123 #pragma mark 计算列数
124 - (int) appColumnCount {
125     int count = 0;
126     count = self.view.frame.size.width / APP_WIDTH;
127    
128     if ((int)self.view.frame.size.width % (int)APP_WIDTH == 0) {
129         count--;
130     }
131    
132     return count;
133 }
134 
135 #pragma mark 计算行数
136 - (int) appRowCount {
137     int count = 0;
138     count = (self.view.frame.size.height - MARGIN_HEAD) / APP_HEIGHT;
139    
140     if ((int)(self.view.frame.size.height - MARGIN_HEAD) % (int)APP_HEIGHT == 0) {
141         count--;
142     }
143    
144     return count;
145 }
146 @end

 

#1. 放入了Images.xcassets中的文件只能通过[UIImage imageNamed:(NSString *) imageName] 访问吗?

转载于:https://www.cnblogs.com/hellovoidworld/p/4119744.html

没有更多推荐了,返回首页