百思不得姐第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条件过滤),找到赋值,并中止遍历。

相关文章
相关标签/搜索