封裝囚聚、懶加載靖榕、MVC、九宮格顽铸、plist

前言:本文章第一時間出現(xiàn)在一個程序猿的秘密基地專題中茁计,如果您喜歡類似的文章,請您點擊一個程序猿的秘密基地進(jìn)行關(guān)注谓松,在以后的日子里與小編共同成長簸淀!

本案例闡述了以下幾點:

1.封裝(低耦合思想)
2.九宮格的計算思路
3.使用plist文件承載數(shù)據(jù)
4.懶加載模式
5.MVC模式(雖然不是純正的MVC,不過也MVC的條件毒返,也算是個簡單的MVC)

//本案例是一套簡單的MVC租幕,不是純正的MVC。
#define SCREEN [[UIScreen mainScreen] bounds].size
#define COUNT self.myWhiteView.subviews.count
#import "ViewController.h"
#import "shops.h"
#import "ZLShopView.h"
@interface ViewController ()
@property(strong,nonatomic)UIView *myWhiteView;
@property(strong,nonatomic)NSArray *commodiyArray;
@property(strong,nonatomic)UIButton *deleteButton;
@property(strong,nonatomic)UIButton *addButton;
@property(strong,nonatomic)UILabel *HUD;
@end

@implementation ViewController
/** 重寫commodiyArray的Get方法,實現(xiàn)懶加載plist文件*/
-(NSArray *)commodiyArray{
    //重寫Get方法時拧簸,下面?和?處不能使用self打點調(diào)用劲绪,會造成死循環(huán)。(因為用self打點調(diào)用的就是此方法)
    if (!_commodiyArray) {//?
        NSArray *dictArray=[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Commodiy" ofType:@"plist"]];
        NSMutableArray *mutableArray=[[NSMutableArray alloc]init];
        for (NSDictionary *dict in dictArray) {
            shops *shop=[shops shopsWithDict:dict];
            [mutableArray addObject:shop];
        }
        _commodiyArray=mutableArray;
    }
    return _commodiyArray;//?
}
- (void)viewDidLoad {
    self.view.backgroundColor=[UIColor lightGrayColor];
    self.addButton=[self addButtonWithFrame:CGRectMake(70, 30, 50, 50) NormalImageNamed:@"add" HighlightedImageNamed:@"add_highlighted" DisabledImageNamed:@"add_disabled" action:@selector(buttonClick:) Tag:1];
    [self addLabel];
    self.deleteButton=[self addButtonWithFrame:CGRectMake(255, 30, 50, 50) NormalImageNamed:@"remove" HighlightedImageNamed:@"remove_highlighted" DisabledImageNamed:@"remove_disabled" action:@selector(buttonClick:) Tag:2];
    self.deleteButton.enabled=NO;
    [self addWhiteView];
}
#pragma mark- 添加商品
-(void)addCommodiyView{
    //此處會去調(diào)用shopView;
    ZLShopView *myCommodiyView=[ZLShopView shopView];
    NSUInteger index=COUNT;
    CGFloat myWhiteViewWidth=80;
    CGFloat myWhiteViewHeight=100;
    int columnNumber=3;
    CGFloat LineSpacing=10;
    CGFloat columnSpacing=(self.myWhiteView.frame.size.width-myWhiteViewWidth*columnNumber)/(columnNumber-1);
    NSUInteger i=index%columnNumber;
    CGFloat myWhiteViewX=(myWhiteViewWidth+columnSpacing)*i;
    NSUInteger j=index/columnNumber;
    CGFloat myWhiteViewY=(myWhiteViewHeight+LineSpacing)*j;
    //此處會觸發(fā)ZLShopView的layoutSubviews方法
    myCommodiyView.frame=CGRectMake(myWhiteViewX, myWhiteViewY, myWhiteViewWidth, myWhiteViewHeight);
    [self.myWhiteView addSubview:myCommodiyView];
    //此處在給ZLShopView里的模型屬性賦值
    myCommodiyView.shop=self.commodiyArray[index];
}
#pragma mark- 添加白色容納商品的view
-(void)addWhiteView{
    self.myWhiteView=[[UIView alloc]initWithFrame:CGRectMake(20, 140, 330, 400)];
    self.myWhiteView.backgroundColor=[UIColor whiteColor];
    [self.view addSubview:self.myWhiteView];
}
#pragma mark- 添加切換布局label
-(void)addLabel{
    UILabel *myLabel=[[UILabel alloc]initWithFrame:CGRectMake(150, 45, 70, 20)];
    myLabel.text=@"切換布局";
    myLabel.textColor=[UIColor blueColor];
    [self.view addSubview:myLabel];
}
#pragma mark- 封裝創(chuàng)建Button的方法
-(UIButton *)addButtonWithFrame:(CGRect)frame NormalImageNamed:(NSString *)normalString HighlightedImageNamed:(NSString *)highlightedString DisabledImageNamed:(NSString *)disabledString action:(nonnull SEL)action Tag:(NSInteger)tag{
    UIButton *myButton=[[UIButton alloc]initWithFrame:frame];
    [myButton setImage:[UIImage imageNamed:normalString] forState:UIControlStateNormal];
    [myButton setImage:[UIImage imageNamed:highlightedString] forState:UIControlStateHighlighted];
    [myButton setImage:[UIImage imageNamed:disabledString] forState:UIControlStateDisabled];
    myButton.tag=tag;
    [myButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:myButton];
    return myButton;
}
#pragma mark- "添加"和"刪除"按鈕的點擊事件
-(void)buttonClick:(UIButton *)sender{
    if (sender.tag==1) {
        [self addCommodiyView];
        [self detectionButtonState:sender];
        return;
    }
    [[self.myWhiteView.subviews lastObject] removeFromSuperview];
    [self detectionButtonState:sender];
}
/** 檢查按鈕狀態(tài)*/
-(void)detectionButtonState:(UIButton *)sender{
    self.deleteButton.enabled=COUNT!=0?YES:NO;
    self.addButton.enabled=COUNT==self.commodiyArray.count?NO:YES;
    if (self.deleteButton.enabled==NO||self.addButton.enabled==NO) {
        [self addHUD];
        self.HUD.text=(self.deleteButton.enabled==NO)?@"商品已經(jīng)清空":@"商品已經(jīng)爆滿";
    }
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.HUD removeFromSuperview];
    });
}
-(void)addHUD{
    self.HUD=[[UILabel alloc]init];
    self.HUD.center=self.myWhiteView.center;
    self.HUD.bounds=CGRectMake(0, 0, 105, 20);
    self.HUD.backgroundColor=[UIColor lightGrayColor];
    [self.view addSubview:self.HUD];
}
//HUD是專業(yè)術(shù)語贾富,又稱:蒙版歉眷、遮蓋、指示器颤枪。是為了讓用戶體驗更好汗捡,起到提示效果
@end

shops.h

#import <Foundation/Foundation.h>

@interface shops : NSObject
/** 圖片名*/
@property(copy,nonatomic)NSString *imageName;
/** 商品名字*/
@property(copy,nonatomic)NSString *name;
//字典轉(zhuǎn)模型方法
-(instancetype)initWithDict:(NSDictionary *)dict;
//此為便利構(gòu)造方法
+(instancetype)shopsWithDict:(NSDictionary *)dict;
@end

shops.m

#import "shops.h"

@implementation shops
-(id)initWithDict:(NSDictionary*)dict{
    if (self=[super init]) {
        self.name=dict[@"imageName"];
        self.imageName=dict[@"image"];
    }
    return self;
}
+(id)shopsWithDict:(NSDictionary *)dict{
    return [[self alloc]initWithDict:dict];
}
@end

ZLShopView.h

//view的封裝思想:如果一個View的內(nèi)部的子控件比較多,一般會考慮自定義一個view畏纲,把它內(nèi)部的子控件屏蔽起來扇住,不讓外界關(guān)心
//外界可以傳入對應(yīng)的模型數(shù)據(jù)給View,view拿到模型數(shù)據(jù)后給內(nèi)部的子控件設(shè)置對應(yīng)的數(shù)據(jù)
#import <UIKit/UIKit.h>
@class shops;
//此是每件商品的創(chuàng)建類盗胀,在這個類中就應(yīng)該設(shè)置商品的圖片以及商品的名字艘蹋,更重要的是商品的信息應(yīng)該是設(shè)置在內(nèi)部,而不是把商品的信息暴露在外部票灰,也就是說一個商品的創(chuàng)建應(yīng)該是它自己的事女阀,至于它叫什么長什么樣也應(yīng)該是它自己的事,外界的ViewController不應(yīng)該知道屑迂。所以關(guān)于商品的屬性應(yīng)該是寫在.m
@interface ZLShopView : UIView
/** 模型對象*/
@property(strong,nonatomic)shops *shop;
//此為便利構(gòu)造方法
+(instancetype)shopView;
@end
/*
 封裝控件的基本步驟:
 1.在initWithFrame:方法中添加子控件浸策,提供便利構(gòu)造的方法
 2.在layoutSubviews方法中設(shè)置子控件的frame(一定要調(diào)用父類的layoutSubviews)
 3.增加模型屬性,在模型屬性set方法中設(shè)置數(shù)據(jù)到子控件上
 */

ZLShopView.m

#import "ZLShopView.h"
#import "shops.h"
//此處是類擴(kuò)展惹盼。類擴(kuò)展用的是()的榛,里面不要寫東西,寫了東西就是類別
@interface ZLShopView()
/** 圖片視圖*/
@property(weak,nonatomic)UIImageView *myImageView;
/** 文字視圖*/
@property(weak,nonatomic)UILabel *myLabel;
@end

@implementation ZLShopView
#pragma mark- 加載子控件第一種是重寫init方法逻锐,在view被創(chuàng)建時加載子控件
/*
 //重寫一個控件的初始化方法夫晌,就重寫initWithFrame,init方法內(nèi)部會自動調(diào)用initWithFrame方法昧诱。
 -(instancetype)initWithFrame:(CGRect)frame{
 //雖然這里frame已經(jīng)有了晓淀,但是不建議用這個frame,因為不能排除傳進(jìn)來的frame是空的。還是應(yīng)該去重寫layoutSubviews盏档,因為只要本類有了尺寸或尺寸在后面進(jìn)行了修改凶掰,它都會來調(diào)用layoutSubviews這個方法,所以在layoutSubviews方法內(nèi)設(shè)置子控件的尺寸才是最準(zhǔn)確的蜈亩。
 if (self=[super initWithFrame:frame]) {
 UIImageView *myImageView=[[UIImageView alloc]init];
 [self addSubview:myImageView];
 _myImageView=myImageView;
 UILabel *myLabel=[[UILabel alloc]init];
 myLabel.textAlignment=NSTextAlignmentCenter;
 [self addSubview:myLabel];
 _myLabel=myLabel;
 }
 return self;
 }
*/
#pragma mark- 加載子控件第二種是懶加載懦窘,當(dāng)系統(tǒng)訪問控件的get方法時在來創(chuàng)建子控件
//懶加載imageView子控件
-(UIImageView *)myImageView{
    if (!_myImageView) {
        UIImageView *myImageView=[[UIImageView alloc]init];
        [self addSubview:myImageView];
        _myImageView=myImageView;
    }
    return _myImageView;
}
-(UILabel *)myLabel{
    if (!_myLabel) {
        UILabel *myLabel=[[UILabel alloc]init];
        myLabel.textAlignment=NSTextAlignmentCenter;
        [self addSubview:myLabel];
        _myLabel=myLabel;
    }
    return _myLabel;
}
//便利構(gòu)造方法的實現(xiàn)
+(instancetype)shopView{
    return [[self alloc]init];
}
/*
 這個方法專門用來布局子控件,一般在這里設(shè)置子控件的frame;
 當(dāng)控件本身的尺寸發(fā)生改變的時候稚配,系統(tǒng)會自動調(diào)用此方法畅涂。
 本案例中是因為ViewController里的
   myCommodiyView.frame=CGRectMake(myWhiteViewX, myWhiteViewY, myWhiteViewWidth, myWhiteViewHeight);
 這個方法觸發(fā)了這個方法。
 */
-(void)layoutSubviews{
    //一定要調(diào)用父類的layoutSubviews道川;
    [super layoutSubviews];
    CGFloat myWhiteViewWidth=self.frame.size.width;
    CGFloat myWhiteViewHeight=self.frame.size.height;
    self.myImageView.frame=CGRectMake(0, 0, myWhiteViewWidth, myWhiteViewWidth);
    self.myLabel.frame=CGRectMake(0, myWhiteViewWidth, myWhiteViewWidth, myWhiteViewHeight-myWhiteViewWidth);
}
//重寫模型的set方法午衰,拿到模型立宜,賦值給子控件
-(void)setShop:(shops *)shop{
    _shop=shop;
    self.myImageView.image=[UIImage imageNamed:shop.imageName];
    self.myLabel.text=shop.name;
}
@end

屏幕快照 2016-06-05 下午1.03.25.png

效果圖及效果要求如下:

屏幕快照_2016-06-05_下午1_08_24.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市臊岸,隨后出現(xiàn)的幾起案子橙数,更是在濱河造成了極大的恐慌,老刑警劉巖帅戒,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灯帮,死亡現(xiàn)場離奇詭異,居然都是意外死亡逻住,警方通過查閱死者的電腦和手機(jī)钟哥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鄙信,“玉大人瞪醋,你說我怎么就攤上這事忿晕∽肮睿” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵践盼,是天一觀的道長鸦采。 經(jīng)常有香客問我,道長咕幻,這世上最難降的妖魔是什么渔伯? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮肄程,結(jié)果婚禮上锣吼,老公的妹妹穿的比我還像新娘。我一直安慰自己蓝厌,他們只是感情好玄叠,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拓提,像睡著了一般读恃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上代态,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天寺惫,我揣著相機(jī)與錄音,去河邊找鬼蹦疑。 笑死西雀,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的歉摧。 我是一名探鬼主播蒋搜,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼篡撵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了豆挽?” 一聲冷哼從身側(cè)響起育谬,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎帮哈,沒想到半個月后膛檀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡娘侍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年咖刃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憾筏。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嚎杨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出氧腰,到底是詐尸還是另有隱情枫浙,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布古拴,位于F島的核電站箩帚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黄痪。R本人自食惡果不足惜紧帕,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桅打。 院中可真熱鬧是嗜,春花似錦、人聲如沸挺尾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潦嘶。三九已至涩嚣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掂僵,已是汗流浹背航厚。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锰蓬,地道東北人幔睬。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像芹扭,于是被迫代替她去往敵國和親麻顶。 傳聞我的和親對象是個殘疾皇子赦抖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)辅肾,斷路器队萤,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,140評論 25 707
  • 對話上馬云曾經(jīng)說過:一個企業(yè)從成立那一刻起,就已經(jīng)注定了死亡矫钓,我所要做的就是要無限期的延長它的存活期要尔,推遲死亡到來...
    octopusvulgaris閱讀 476評論 0 0
  • 白色的圍巾赵辕,小手微涼,她注視針線的雙眸概龄,可藏著誰的夢还惠。鴿子停在路燈上,拿石頭砸它私杜,繞著路燈跑呀跑蚕键,那些孩子,可還好...
    抓星星的小超閱讀 380評論 0 1
  • 雖然我閉上眼睛 看不見我自己 但是我卻可以看見你 我常常在想 想念一個人的時候世界會是什么模樣 后來我發(fā)現(xiàn) 世界沒...
    田園牧歌928閱讀 226評論 0 1