百思不得姐第1天

一:項目環境的搭建:數據庫

項目環境的搭建包括:1:新建類的前綴   2:項目支持的旋轉方向,版本   3:項目名稱,軟件名稱 4:APP的icon,啓動圖片的設置 5:項目的文件夾分層 6:根控制器的設置 等  數組

具體詳情請參照新浪微博的項目環境配置安全

 

二:cocoaPods的安裝與使用app

1:具體參照新浪微博項目cocoaPods的安裝與使用:安裝並導入所須要的依賴庫框架

 

三:百思不得姐主框架的搭建dom

1:刪除storyBoard,從新定義窗口的根視圖控制器ide

#import "AppDelegate.h"
#import "CQTabBarViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    //1:添加窗口的根視圖控制器
    
    CQTabBarViewController *tab = [[CQTabBarViewController alloc]init];
    self.window.rootViewController = tab;
    

    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

2:構建窗口的根視圖控制器:模塊化

//
//  CQTabBarViewController.h
//  百思不得姐
//
//  Created by cqb on 16/8/25.
//  Copyright © 2016年 cqb. All rights reserved.
//窗口的根視圖控制器:CQTabBarViewController

#import <UIKit/UIKit.h>

@interface CQTabBarViewController : UITabBarController


@end
#import "CQTabBarViewController.h"
#import "CQFollowViewController.h"
#import "CQMeViewController.h"
#import "CQNewViewController.h"
#import "CQEsencesViewController.h"
#import "CQCustomTabBar.h"
#import "CQCustomNavViewcontrollerViewController.h"
@interface CQTabBarViewController ()<CQCustomTabBarDelegate>

@end

@implementation CQTabBarViewController



- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1:設置tabBarItem的屬性
    [self setupTabBarItemAttribute];
    
    //2:添加子控制器
    [self addChildViewControllers];
    
    //3:添加自定義的tabBar
    [self addCustomTabbar];

 
}

/**
 *    設置tabBarItem的屬性
 */

- (void)setupTabBarItemAttribute {
    
    UITabBarItem *tabItem = [UITabBarItem appearance];
    
    //1:設置Normal狀態下的文字屬性
    NSMutableDictionary *itemNormalTitleDic = [NSMutableDictionary dictionary];
    itemNormalTitleDic[NSFontAttributeName] = Font(13);
    itemNormalTitleDic[NSForegroundColorAttributeName] = [UIColor grayColor];
    [tabItem setTitleTextAttributes:itemNormalTitleDic forState:UIControlStateNormal];
    
    //2:設置select狀態下的文字屬性
    NSMutableDictionary *itemSelectTitleDic = [NSMutableDictionary dictionary];
    itemSelectTitleDic[NSFontAttributeName] = Font(13);
    itemSelectTitleDic[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
    [tabItem setTitleTextAttributes:itemSelectTitleDic forState:UIControlStateSelected];
    
}

/**
 *    添加子控制器
 */

- (void)addChildViewControllers {
    
    /**
     *    精華
     */
    [self addChildViewController: [[CQCustomNavViewcontrollerViewController alloc]initWithRootViewController:[[CQEsencesViewController  alloc]init]] title:@"精華"  image:@"tabBar_essence_icon"  selectedImage:@"tabBar_essence_click_icon"];
    
    /**
     *    新帖
     */
    [self addChildViewController: [[CQCustomNavViewcontrollerViewController alloc]initWithRootViewController:[[CQNewViewController  alloc]init]] title:@"新帖"  image:@"tabBar_new_icon"  selectedImage:@"tabBar_new_click_icon"];
    
    
    /**
     *    關注
     */
    [self addChildViewController: [[CQCustomNavViewcontrollerViewController alloc]initWithRootViewController:[[CQFollowViewController  alloc]init]] title:@"關注"  image:@"tabBar_friendTrends_icon"  selectedImage:@"tabBar_friendTrends_click_icon"];
    
    /**
     *    我
     */
    [self addChildViewController: [[CQCustomNavViewcontrollerViewController alloc]initWithRootViewController:[[CQMeViewController  alloc]init]] title:@""  image:@"tabBar_me_icon"  selectedImage:@"tabBar_me_click_icon"];
}


- (void)addChildViewController:(UIViewController*)vc  title:(NSString*)title  image:(NSString*)imageName  selectedImage:(NSString*)selectedImageName  {
    
    //1:設置標題
    vc.tabBarItem.title = title;
    
    //2:設置圖片
    //  normal
    vc.tabBarItem.image = [UIImage imageNamed:imageName];
    
    //select
    vc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImageName];
    
    [self addChildViewController:vc];
    
}
/**
 *    添加自定義的tabBar
 */

- (void)addCustomTabbar {
    
     CQCustomTabBar *tab =  [CQCustomTabBar customTabBar];
     tab.delegate = self;
    [self setValue:tab forKeyPath:@"tabBar"];
}

/**
 *CQCustomTabBarDelegate 代理方法
 */

- (void)customTabBar:(CQCustomTabBar *)customTabBar didSelecteCenterButton:(UIButton *)btn {
    
    CQBFUNC
}
@end

3:從新自定義導航控制器:佈局

#import <UIKit/UIKit.h>

@interface CQCustomNavViewcontrollerViewController : UINavigationController

@end
#import "CQCustomNavViewcontrollerViewController.h"

@interface CQCustomNavViewcontrollerViewController ()<UIGestureRecognizerDelegate>

@end

@implementation CQCustomNavViewcontrollerViewController

/**
 *    1:設置導航欄的標題,item屬性
 */
+(void)initialize {
    
    //1:設置導航欄的主題
    [self setupNavBarTheme];
    
    //2:設置導航欄上的item屬性
    [self setupNavBarItem];
}

//1:設置導航欄的主題
+(void)setupNavBarTheme {
    
    UINavigationBar *appearance = [UINavigationBar appearance];
    //1:設置導航欄的背景圖片,背景色:tintColor
    [appearance setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
    
    //2:設置導航標題屬性
    NSMutableDictionary *titleAttribute = [NSMutableDictionary dictionary];
    titleAttribute[NSForegroundColorAttributeName] = [UIColor blackColor];
    titleAttribute[NSFontAttributeName] = [UIFont boldSystemFontOfSize:18];
    [appearance setTitleTextAttributes:titleAttribute];
    
}

//2:設置導航欄上的item屬性
+(void)setupNavBarItem {
    
    UIBarButtonItem *appearance = [UIBarButtonItem appearance];
    
    //設置文字屬性
    
    //1:normal
    NSMutableDictionary *normalAttribute = [NSMutableDictionary dictionary];
    normalAttribute[NSFontAttributeName] = Font(15);
    normalAttribute[NSForegroundColorAttributeName] = [UIColor blackColor];
    [appearance setTitleTextAttributes:normalAttribute forState:UIControlStateNormal];
 
    //2:高亮
    NSMutableDictionary *selectedAttribute = [NSMutableDictionary dictionary];
    selectedAttribute[NSFontAttributeName] = Font(15);
    selectedAttribute[NSForegroundColorAttributeName] = [UIColor grayColor];
    [appearance setTitleTextAttributes:selectedAttribute forState:UIControlStateHighlighted];
    
}



- (void)viewDidLoad {
    [super viewDidLoad];
  
    //1:當自定義導航控制器的時候,系統的左滑手勢會失效
    self.interactivePopGestureRecognizer.delegate = self;
    
}
/**
 *    攔截push請求設置每一個push控制器的左右item按鈕
 *
 *    @param viewController    即將被壓棧的kongzjqi
 *    @param animated            是否動畫
 */
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {

    if (self.viewControllers.count > 0) {
       
        //1:設置即將壓棧控制器的左右item
        
        //左側返回按鈕
        viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTitle:@"返回" image:@"navigationButtonReturn" HighlightImage:@"navigationButtonReturnClick" target:self action:@selector(pop)];

        
        //右側按鈕
        viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTitle:nil image:@"MainTagSubIcon" HighlightImage:@"MainTagSubIconClick" target:self action:@selector(popRoot)];
        
        //2:push的時候隱藏tabBar
        viewController.hidesBottomBarWhenPushed = YES;
        
    }
    
    
    [super pushViewController:viewController animated:animated];
    
}

/**
  左右按鈕的點擊方法
 */

//左側返回按鈕
- (void)pop {
    
    [self popViewControllerAnimated:YES];
}

//右側按鈕

- (void)popRoot {
    
    [self popToRootViewControllerAnimated:YES];
}


/**
 *UIGestureRecognizerDelegate:代理方法:
 */
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    
    return self.childViewControllers.count > 1;
//    return self.viewControllers.count > 1;
}

@end

4:自定義tabBar取代系統的tabBarpost

#import <UIKit/UIKit.h>

@class CQCustomTabBar;
@protocol CQCustomTabBarDelegate <NSObject>

@optional

- (void)customTabBar:(CQCustomTabBar*)customTabBar didSelecteCenterButton:(UIButton*)btn;

@end


@interface CQCustomTabBar : UITabBar

+(instancetype)customTabBar;

@property (nonatomic,weak)id <CQCustomTabBarDelegate>Delegate;
@end
#import "CQCustomTabBar.h"
@interface CQCustomTabBar ()
/*中間的按鈕*/
@property (nonatomic,weak)UIButton *centerButton;

@end
@implementation CQCustomTabBar

- (UIButton*)centerButton {
    
    if (!_centerButton) {
        
        UIButton *btn = [[UIButton alloc]init];
        [btn setBackgroundColor:[UIColor clearColor]];
        [btn setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
        [btn setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
        [btn addTarget:self action:@selector(clickCenterBtn:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:btn];
        self.centerButton = btn;
    
    }
    
    return _centerButton;
}

+(instancetype)customTabBar {
    
    return [[self alloc]init];
}

- (instancetype)initWithFrame:(CGRect)frame {
    
    if (self = [super initWithFrame:frame]) {
        
        //1:設置自身的屬性
        [self setupAtrtribute];
        
    }
    
    return self;
}

/**
 *    1:設置自身的屬性
 */

- (void)setupAtrtribute {
    
    [self setBackgroundImage:[UIImage imageNamed:@"tabbar-light"]];

}

/**
 *    2:佈局子控件
 */
- (void)layoutSubviews {
  
    [super layoutSubviews];
   //1:先佈局已經添加的四個子控件
    
    CGFloat btnWidth = self.CQ_Width / (self.items.count +1);
    CGFloat btnHeight = self.CQ_Height;
    CGFloat btnY = 0;//爲0時能夠不寫
    
    NSUInteger index = 0;
    
    for (UIView *tabBarButton in self.subviews) {
        
    if (![tabBarButton isKindOfClass:[NSClassFromString(@"UITabBarButton") class]])   continue;//return;
       
        if (index >= 2) {
            /*也能夠:
             
             if (index == 2) {
             
             //佈局中間鈕
             self.centerButton.CQ_Width = btnWidth;
             self.centerButton.CQ_Height = btnHeight;
             self.centerButton.CQ_X = index *btnWidth;
             self.centerButton.CQ_Y = btnY;
             }
             */
         
            tabBarButton.CQ_X = (index + 1) *btnWidth;
            
        }else {
            
            tabBarButton.CQ_X = index *btnWidth;
        }
        tabBarButton.CQ_Y = btnY;
        tabBarButton.CQ_Height = btnHeight;
        tabBarButton.CQ_Width = btnWidth;

        index ++ ;
        
    }
    
    self.centerButton.CQ_Width = btnWidth;
    self.centerButton.CQ_Height = btnHeight;
    self.centerButton.CQ_CenterX = self.CQ_Width *0.5;
    self.centerButton.CQ_CenterY = self.CQ_Height *0.5;
    
}
/**
 *    中間按鈕的點擊回調
 */

- (void)clickCenterBtn:(UIButton*)btn {
    
    if (self.Delegate && [self.Delegate respondsToSelector:@selector(customTabBar:didSelecteCenterButton:)]) {
        
        [self.Delegate customTabBar:self didSelecteCenterButton:btn];
    }
}
@end

5:項目中的分類文件:

 1:UIBarButtonItem分類:設置導航欄上的左右按鈕

//
//  UIBarButtonItem+CQBarButtonItem.h
//  百思不得姐
//
//  Created by cqb on 16/8/25.
//  Copyright © 2016年 cqb. All rights reserved.
//UIBarButtonItem分類:設置導航欄上的左右按鈕

#import <UIKit/UIKit.h>

@interface UIBarButtonItem (CQBarButtonItem)

+(instancetype)itemWithTitle:(NSString*)title image:(NSString*)imageName HighlightImage:(NSString*)highlightImageName target:(id)target action:(SEL)action;

@end
#import "UIBarButtonItem+CQBarButtonItem.h"

@implementation UIBarButtonItem (CQBarButtonItem)

+(instancetype)itemWithTitle:(NSString*)title image:(NSString*)imageName HighlightImage:(NSString*)highlightImageName target:(id)target action:(SEL)action {
    
    UIButton *btn = [[UIButton alloc]init];
    if (title.length){
       [btn setTitle:title forState:UIControlStateNormal];
       [btn setTitleColor:RGB(46, 46, 47) forState:UIControlStateNormal];
       [btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    }
    [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    [btn setImage:[UIImage imageNamed:highlightImageName] forState:UIControlStateHighlighted];
    btn.titleLabel.font = Font(15);
    [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    [btn sizeToFit];
#pragma mark -- 此句代碼是調整左右按鈕距離邊框的位置,前提是必須有btn已經有了size
    btn.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
    return [[UIBarButtonItem alloc]initWithCustomView:btn];
}
@end

2:UIView的分類

//  UIView+CQView.h
//  百思不得姐
//
//  Created by cqb on 16/8/25.
//  Copyright © 2016年 cqb. All rights reserved.
//分類不生成帶下劃線的成員變量,因此重寫set不用下劃線賦值

#import <UIKit/UIKit.h>

@interface UIView (CQView)
@property (nonatomic,assign)CGFloat CQ_X;
@property (nonatomic,assign)CGFloat CQ_Y;
@property (nonatomic,assign)CGFloat CQ_Width;
@property (nonatomic,assign)CGFloat CQ_Height;
@property (nonatomic,assign)CGFloat CQ_CenterX;
@property (nonatomic,assign)CGFloat CQ_CenterY;
@property (nonatomic,assign)CGSize CQ_Size;

@end
//
//  UIView+CQView.m
//  百思不得姐
//
//  Created by cqb on 16/8/25.
//  Copyright © 2016年 cqb. All rights reserved.
//

#import "UIView+CQView.h"

@implementation UIView (CQView)

- (void)setCQ_X:(CGFloat)CQ_X {
    
    CGRect frame = self.frame;
    frame.origin.x = CQ_X;
    self.frame = frame;
}

- (CGFloat)CQ_X {
    
    return self.frame.origin.x;
}


- (void)setCQ_Y:(CGFloat)CQ_Y {
    
    CGRect frame = self.frame;
    frame.origin.y = CQ_Y;
    self.frame = frame;

}

- (CGFloat)CQ_Y {
    
    return self.frame.origin.y;
}


- (void)setCQ_Width:(CGFloat)CQ_Width {
    
    CGRect frame = self.frame;
    frame.size.width = CQ_Width;
    self.frame = frame;

}

- (CGFloat)CQ_Width {
    
    return self.frame.size.width;
}

- (void)setCQ_Height:(CGFloat)CQ_Height {
    
    CGRect frame = self.frame;
    frame.size.height = CQ_Height;
    self.frame = frame;

}

- (CGFloat)CQ_Height {
    
    return self.frame.size.height;
}

- (void)setCQ_Size:(CGSize)CQ_Size {
    
    CGRect frame = self.frame;
    frame.size = CQ_Size;
    self.frame = frame;

    
}

- (CGSize)CQ_Size {
    
    return self.frame.size;
}

- (void)setCQ_CenterX:(CGFloat)CQ_CenterX {
    
    CGPoint center = self.center;
    center.x = CQ_CenterX;
    self.center = center;

}

- (CGFloat)CQ_CenterX {
    
    return self.center.x;
}


- (void)setCQ_CenterY:(CGFloat)CQ_CenterY {
    
    CGPoint center = self.center;
    center.y = CQ_CenterY;
    self.center = center;
}

- (CGFloat)CQ_CenterY {
    
    return self.center.y;
}

@end

6:項目中的pch文件宏定義:

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#import "UIBarButtonItem+CQBarButtonItem.h"
#import "UIView+CQView.h"
/**
 *    1:配置顏色的宏
 */

#define  RGBCOLOR(a,b,c,d) [UIColor colorWithRed:(a)/255.0 green:(b)/255.0 blue:(c)/255.0 alpha:d]

#define RGB(a,b,c)  RGBCOLOR(a,b,c,1)

#define RGBRANDOM   RGB(arc4random_uniform(255),arc4random_uniform(255),  arc4random_uniform(255))


/**
 *    2:打印的相關配置
 */


#ifdef DEBUG

#define CQLog(...)   NSLog(__VA_ARGS__)

#else

#define CQLog(...)

#endif



/**
 *    3:調試配置
 */

#define CQBFUNC  CQLog (@"+++++++++++%s+++++++++++++",__func__);


/**
 *    4:單例宏配置:注意小括號最好不要留有空格
 */

//.h文件

#define CQSingletonInterface(Class)    +(instancetype)shared##Class

//.m文件

#define CQSingletonImplementation(Class)\
\
static  id  _instance;\
+(instancetype)shared##Class {\
\
\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
\
        _instance = [[self alloc]init];\
\
    });\
\
    return _instance;\
}\
\
+(instancetype)allocWithZone:(struct _NSZone *)zone {\
\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
\
        _instance = [super allocWithZone:zone];\
    });\
\
    return _instance;\
}\
\
- (instancetype)copyWithZone:(NSZone *)zone\
{\
    return _instance;\
}

/**
 *    字體的宏配置
 */

#define Font(a)  [UIFont systemFontOfSize:a]

/**
 *    屏幕寬高
 */

#define SCREENWIDTH  [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT  [UIScreen mainScreen].bounds.size.height 

/**
 *    全局背景色
 */

#define AllBackgroundColor  RGB(187,187,187)



#endif /* PrefixHeader_pch */

總結:

1:窗口的根控制器繼承UITabBarController,在自定義的CQTabBarViewController中的viewDidload方法裏抽方法封裝調用,須要作3件事:1:設置tabBarItem的不一樣狀態下的文字屬性 :拿到全局tabBarItem,再利用setTitleTextAttributes  forState,設置不一樣狀態下的文字屬性  2:添加全部子控制器:由於須要添加tabBar上的四個子控制器,有大量重複的代碼,要想到抽代碼封裝,將相同的部分抽成方法,不一樣的部分做爲參數調用:因此抽成方法,傳子控制器VC,title,Image,selectImage(傳入子控制器爲導航控制器),在方法中設置tabBaritem的標題不一樣狀態下的圖片,vc.tabBarItem.title  vc.tabBarItem.Image  vc.tabBarItem.selecteImage,最後調用addChildViewcontroller,添加子控制器 3:須要利用自定義tabBar利用kvc,setValue forKeyPath,替換掉系統的tabBar。

2:自定義導航控制器:在自定義導航控制器中須要作三件事:1:在+(void)initialize方法中設置全局的導航欄UINavigationBar

的外觀:背景圖片,背景色:tintColor,並設置導航欄上標題文字屬性,setTitleTextAttributes  。還須要在此方法中設置導航欄上的全局左右按鈕UIBarButtonItem,設置不一樣狀態下的文字屬性,常態,選中,高亮。 2:在viewDidLoad中設置手勢代理:由於只要是自定義導航欄系統自帶的左滑效果就會消失,因此要從新回覆左滑手勢,就要設置手勢代理。self.interactivePopGestureRecognizer.delegate = self;並實現手勢的代理方法:- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer,當導航控制器的棧裏的控制器個數大於1的時候才讓其恢復左滑效果。

   return self.childViewControllers.count > 1;

//    return self.viewControllers.count > 1;

兩種方法均可以拿到導航控制器的子控制器的數組。

3:須要攔截push方法:攔截push的目的是:爲每個push到棧裏的控制器,除了首頁的控制器,設置統一的返回按鈕,而且push的時候隱藏底部的tabBar。並實現左右按鈕的點擊方法

4:自定義底部的tabBar:繼承系統的tabBar,參照view的封裝方法:1:類方法快速返回對象,內部調用alloc init ,alloc init內部調用alloc initWithFrame 方法,在初始化方法中設置自身的屬性或是一次性設置代碼  2:懶加載控件(屬性定義strong和weak修飾均可以),在懶加載方法中設置控件的屬性。並添加到其父控件上 3:重寫layoutSubView方法,不要忘記調用super,且此方法配合setNeedsLayout和layoutIfneed配合使用:在此方法內設置控件的frame,如何拿到控件?1:屬性,成員變量,枚舉tag值(直接取,或是遍歷父控件的子控件數組,經過tag值取出,tag值通常不要設爲0,不安全,由於全部控件默認的tag值都爲0,經過self.subviews,count 也能夠設置tag值),或是繼承父類直接從父類屬性獲取 2:將建立的控件放在一個屬性定義的大數組中,如果含有不一樣類的控件則兩兩放在大數組中,在layoutSubView裏從數組中取出 3:遍歷父控件的子控件數組:1:self.subViews(UIView和scroll隱藏掉兩個滾動條後是最純潔的view,除了本身添加的不含有任何子控件),須要index就採用int i 遍歷,不須要就能夠採用for in快速遍歷,並在外部定義index,內部index++,來記錄索引值。在遍歷時,先要作條件過濾(1:continue 2:return過濾,不執行return下面的代碼,3:break,跳出循環,再也不循環)找到後設置值,並中止遍歷 2:如果遍歷父控件的self.subViews子控件數組,有時候系統父控件沒有直接提供屬性使用,這時,能夠打印子控件數組或是經過ViewUI來調試查看所須要的子控件是什麼,這樣就能夠拿到子控件從字符串轉化爲類,NSClassFromString();4:設置frame完畢後:每個封裝view都要對應一個model,因此封裝的view提供model接口,在內部重寫setmodel,爲view設置數據  5:對於封裝view接口的設計:1:把與外界無關的業務邏輯所有封裝在類的內部,類再提供接口供外界訪問,保證外界調用時最簡潔的 2:對於接口的設計:通常用屬性接口經過重寫代替方法接口,是否就提供BOOL屬性接口,不一樣類型,就提供枚舉type接口,外界想訪問類內部的什麼方法,變量就給外部提供屬性接口。6:對於封裝類內部的回調:1:層級較淺時,用協議代理(1:仿照tableView的代理方法設計協議代理 2:有時須要重寫setDelegate方法來,也就是成爲代理以後才能夠去作某些設置)block,二者均可以,當兩個類須要相互回調時,能夠給協議代理或是block設置返回值,就能夠實現兩個類相互回調 2:層級較深的時候:能夠利用通知回調,傳值,其中通知能夠在當前線程或是子線程中執行(只看post通知的時候在哪一個線程裏,註冊觀察者後,執行通知方法就在哪一個線程),其中註冊觀察者也能夠用block方式註冊觀察者,並指定收到通知後的block任務在哪一個線程中執行(也可實現一次性的通知,在block中執行完任務後,就取消觀察者),若是採用block的方式註冊的觀察者,要以熟悉定義id類型返回值類接受block通知的返回值,以便在dealloc中註銷觀察者。通常項目中的通知名都寫在配置常量的類裏   7:在封裝類的內部監聽系統類或是屬性:1:查看子類有沒有系統代理方法,通知方法,或是繼承UIControl的能夠addTarget均可以實現監聽,如果子類沒有還能夠查看父類有沒有上述的方法,在查看系統的API時,能夠查看其其英文註釋該方法的使用說明,也能夠按住option鍵點擊某個方法來查看使用說明 2:在開發中遇到問題首先考慮重寫,重寫很是好用,經過重寫父類的方法也能夠對父類行爲進行攔截,覆蓋或是監聽父類的行爲。可是不要忘記調用super,不然父類的行爲就不會響應。

5:1:如果設置某個控件在中間的位置,就能夠考慮用center屬性去設置,設置tabBar中間按鈕的frame時,先設置按鈕的寬高,在設置center,防止出錯,center的x值就爲寬度的一半,center的y值就爲高度的一半 2:若是設置的是tabBar的中心點等於按鈕的中心點就會出錯,tabBar的中心點是相對整個屏幕來計算的,因此如此設置,按鈕就會找不到了,由於按鈕是添加到tabBar上的,因此就要設置相對tabBar的中心點 2:在封裝UIBarButtonItem時,在分類裏,自定義按鈕,調用sizeTofit方法,系統會自動根據按鈕的內容的大小來計算按鈕的寬高,還有一種方法,(1:如果想讓圖片不變形,就設置按鈕大小和圖片大小相等(圖片的大小按像素計算,按鈕的大小等於圖片的大小,就用圖片像素的寬高分別乘以2)2:設置按鈕中imageView的內容模式:center,等比fit,等比fill,fill屬性,center圖片內容居中,等比fit會先使圖片頂部對齊,直到整個圖片在imageView中徹底顯示出來 ,等比fill,保持圖片原來的寬高比伸縮,最後有可能只看到圖片的一部分,fill圖片的默認方式,默認填充整個imageView。)先爲btn設置圖片,在經過btn取出圖片btn.currentImage,title,backgroundImage取出,在設置btn的size。3:設置導航欄上的按鈕距離左右邊框的距離:1:設置btn的內容的edge屬性,btn.contentEdgeInset,左側設置爲負數,則btn的總體內容content就會向左移動,縮短與屏幕的距離,設置正數content就會往右移動,增長了距離 2:自定義NavBar繼承系統的NavBar,重寫layoutsubView方法,遍歷子控件根據條件判斷左右按鈕,拿到左右按鈕的子控件,如果不能拿到,則打印子控件數組,NSClassFromstring(),作條件過濾拿到最後真正的子控件,再調整距離,利用kvc替換系統的NavBar 3:btn的重要的屬性:繼承UIControl都有的contentHorizan內容的對齊方式,btn.contentEdgeInset,btn.titleEdgeInset,btn.imageEdgeInset,當按鈕內部須要要調整title和image的相對位置時:1:自定義UIButton,重寫button的title,iamge從新佈局的方法 2:自定義button,重寫layoutsubview,直接拿到子控件title,iamge去調整frame(1:如果不能直接拿到則遍歷子控件數組,打印或是viewUI查看其所屬的類,NSClassFromstring去作條件過濾拿到 2:利用潤time拿到父類全部私有屬性,利用kvc賦值設置)3:利用btn的對其方式:四個對其方式配合使用,例如,先總體內容左對齊,在設置title或是image,或是content的edge屬性。4:再給UIView或是其餘類寫分類時,最好加上前綴,像sd_iamge,或是mj_refresh,避免與系統定義的變量衝突,分類以屬性定義變量的時候,不會自動生成下劃線的成員變量,因此不用下劃線變量賦值。 5:pch文件通常存放項目中的頭文件,一些打印調試顏色單例或是基本數據的宏定義。在buildsetting中配置pch的路徑,須要刪除的是當前桌面的路徑,保留的是此項目的當前路徑並加上$(SRCROOT).像項目一些通知名,或是一些常量字符串就新建類特地存儲這些全局常量UIKIT_EXTERN 來引用。在配置打印和單例的宏定義時,最好涉及到變量後有小括號時,最好不要留有空格要緊挨着。6:單例的完整寫法:1:在pch文件中配置的單例宏定義就是完整的寫法1:考慮到了線程安全,dispatch_once默認有一把線程鎖 2:當調用share 或是 alloc,或是copy的時候保證獲得的都是同一個對象。alloc內部會調用 allocWithZoon方法,開闢內存空間。調用copy的時候已經保證了兩個方法已經執行完了,如果想重寫-(id)copyWithzoon方法,必須先要遵照NSCopying協議才能夠重寫。

6:如何寫代碼:1:先要整理好邏輯,把邏輯理順了,再去下手去寫代碼 2:對於控制器或是view:要想到分層封裝的思想,將控制器或是view的UI模塊化切分紅一個個模塊,分析模塊內都由哪些控件組成,將零散的控件都封裝一個總體的模塊內(參照新浪微博cell的封裝結構),如果項目中不少地方都會用到此模塊,則考慮將此模塊抽成父類,讓子類去繼承,並擴展不一樣於父類的內容。具體的封裝方法參照view的封裝方法。3:控制器或是封裝view中代碼的編寫:1:在控制器中實現+(void)load,作一些經常使用配置(例如配置MJExtension字典轉模型的配置),該方法只執行一次,而且不用導入頭文件就能夠調用,也就是該類被加載進內存就會調用 +(void)initalize方法改方法也會調用一次,當類被使用的時候也就是第一個方法被調用的時候有且只會調用一次,在該方法中能夠初始化一些配置的設置或是隻須要一次性設置的(自定義導航控制器設置全局導航主題,或是數據庫建表)重寫控制器的init方法,能夠在控制器建立初始化時傳遞參數或是初始化時作一些固定的一次性設置。+(void)loadView方法,重寫此方法能夠更改控制器的self.view  viewDidLoad方法view加載完畢後調用,viewWillAppear 或是viewWillDidAppear 這兩個方法會調用不止一次,只要是界面出現即將出現就會調用pop,dissmiss都會調用,通常在viewWillDidAppear方法中打印控件的信息,由於此時控件已經徹底顯示出來,viewWillDisappear,viewDiddisappear頁面即將消失或是已經消失 的時候調用,dealloc控制器銷燬的時候調用,在此方法中能夠移除通知或是在控制器銷燬的時候傳遞給愛他控制器一些數據信息。2:咱們通常在viewDidLoad方法中採起封裝方法調用 1:當控制器中某個方法含有大量重複的代碼時要考慮抽方法封裝,將相同的代碼抽到方法的內部,不一樣的部分做爲參數傳遞 2:如果代碼中涉及某些業務邏輯的處理或是項目中各個地方均可以用到,則也應考慮到封裝:1:分類封裝:1:當此段業務邏輯與系統某個類有關係時,要想到給系統類寫分類,並且能寫分類儘可能寫分類,由於分類會少建立類,減小內存 2:分類的接口設計:對象方法或是類方法,類方法較對象方法簡餐粗暴,可是當須要傳遞兩個參數的時候能夠考慮利用對象方法,分類中的self指的就是傳遞的參數 2:管理類Tool封裝:單例或是類方法,在類方法中要是想得到單例同樣的成員變量,就用static定義全局變量,該成員變量也能夠採用懶加載模式,只讓其初始化一次,外界如果想訪問該成員變量,則該類能夠提供接口get方法接口,供外界調用(get方法接口也能夠用點語法去調用)3:考慮繼承:將相同的部分抽到父類,不一樣的部分分別在子類中去實現,父類可在.h中暴露方法供子類去重寫(父類可提供標識屬性,供子類去重寫,以便於在父類中區分不一樣子類),子類重寫父類的方法後,也就至關於間接修改了父類的屬性,父類中也就能夠拿到子類修改的屬性。3:控制器或是view中每一行代碼的編寫,都要力求使最簡潔的,要反覆推敲,提煉,直到代碼是最簡潔不能再抽爲止。1:像是hidden或是返回bool值的方法中一句代碼解決 或是利用三目運算簡化ifelse 2:賦值散三部,最上面定位nil,中間賦值,最後賦值 3:有兩個返回值時,只用一個if,分別返回,不用if else 4:當遍歷的時候,先作條件過濾(continue,braek,或是return條件過濾),找到賦值,並中止遍歷。

相關文章
相關標籤/搜索