一:类似于网易的抽屉效果,启动有广告,进入主界面后,点击左上角按钮,侧滑左抽屉,点击右上角,侧滑出右抽屉。点击左抽屉按钮,对视图进行切换
。
二代码:
1:启动图展示广告界面实现:先吧启动图控制器作为窗口的根视图控制器,展示完广告消失后,再切换窗口的根视图控制器为主控制器。其中窗口指的是项目中的主窗口也就是keyWindow,主窗口主要负责接收一些键盘事件,文本框输入事件,若是键盘文本框,textView或是textfield不能输入,则考虑是不是当前窗口是否是主窗口
@interface HMAdViewController ()@end@implementation HMAdViewController- (void)viewDidLoad{ [super viewDidLoad]; // 1.背景图片 UIImageView *bg = [[UIImageView alloc] init]; bg.image = [UIImage imageNamed:@"Default"]; bg.frame = self.view.bounds; [self.view addSubview:bg]; // 2.广告图片(真实的广告图片应该要先下载广告图片) UIImageView *ad = [[UIImageView alloc] init]; ad.image = [UIImage imageNamed:@"ad"]; ad.width = 280; ad.height = 300; ad.centerX = self.view.width * 0.5; ad.y = 60; [self.view addSubview:ad]; // 3.2s后调到下一个主界面 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIWindow *window = [UIApplication sharedApplication].keyWindow; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; window.rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"Main"]; });}@end
2:当启动图广告界面展示完毕后,切换窗口根视图控制器。
1 #import "HMMainViewController.h" 2 #import "HMLeftMenu.h" 3 #import "HMRightMenuController.h" 4 #import "HMNavigationController.h" 5 #import "HMNewsViewController.h" 6 #import "HMReadingViewController.h" 7 #import "HMTitleView.h" 8 9 #define HMNavShowAnimDuration 0.25 10 #define HMCoverTag 100 11 #define HMLeftMenuW 150 12 #define HMLeftMenuH 300 13 #define HMLeftMenuY 50 14 15 @interface HMMainViewController ()16 /** 17 * 正在显示的导航控制器 18 */ 19 @property (nonatomic, weak) HMNavigationController *showingNavigationController; 20 @property (nonatomic, strong) HMRightMenuController *rightMenuVc; 21 @property (nonatomic, weak) HMLeftMenu *leftMenu; 22 @end 23 24 @implementation HMMainViewController 25 26 - (void)viewDidLoad 27 { 28 [super viewDidLoad]; 29 30 // 1.创建子控制器 31 [self setupAllChildVcs]; 32 33 // 2.添加左菜单 34 [self setupLeftMenu]; 35 36 // 3.添加右菜单 37 [self setupRightMenu]; 38 } 39 40 41 /** 42 * 添加右菜单 43 */ 44 - (void)setupRightMenu 45 { 46 HMRightMenuController *rightMenuVc = [[HMRightMenuController alloc] init]; 47 rightMenuVc.view.x = self.view.width - rightMenuVc.view.width; 48 [self.view insertSubview:rightMenuVc.view atIndex:1]; 49 self.rightMenuVc = rightMenuVc; 50 } 51 52 /** 53 * 添加左菜单 54 */ 55 - (void)setupLeftMenu 56 { 57 HMLeftMenu *leftMenu = [[HMLeftMenu alloc] init]; 58 leftMenu.delegate = self; 59 leftMenu.height = HMLeftMenuH; 60 leftMenu.width = HMLeftMenuW; 61 leftMenu.y = HMLeftMenuY; 62 [self.view insertSubview:leftMenu atIndex:1]; 63 self.leftMenu = leftMenu; 64 } 65 66 /** 67 * 创建子控制器 68 */ 69 - (void)setupAllChildVcs 70 { 71 // 1.新闻控制器 72 HMNewsViewController *news = [[HMNewsViewController alloc] init]; 73 [self setupVc:news title:@"新闻"]; 74 75 // 2.订阅控制器 76 HMReadingViewController *reading = [[HMReadingViewController alloc] init]; 77 [self setupVc:reading title:@"订阅"]; 78 79 // 3.图片控制器 80 UIViewController *photo = [[UIViewController alloc] init]; 81 [self setupVc:photo title:@"图片"]; 82 83 // 4.视频控制器 84 UIViewController *video = [[UIViewController alloc] init]; 85 [self setupVc:video title:@"视频"]; 86 87 // 5.跟帖控制器 88 UIViewController *comment = [[UIViewController alloc] init]; 89 [self setupVc:comment title:@"跟帖"]; 90 91 // 6.电台控制器 92 UIViewController *radio = [[UIViewController alloc] init]; 93 [self setupVc:radio title:@"电台"]; 94 } 95 96 - (UIStatusBarStyle)preferredStatusBarStyle 97 { 98 return UIStatusBarStyleLightContent; 99 }100 101 /**102 * 初始化一个控制器103 *104 * @param vc 需要初始化的控制器105 * @param title 控制器的标题106 */107 - (void)setupVc:(UIViewController *)vc title:(NSString *)title108 {109 // 1.设置背景色110 vc.view.backgroundColor = HMRandomColor;111 112 // 2.设置标题113 HMTitleView *titleView = [[HMTitleView alloc] init];114 titleView.title = title;115 vc.navigationItem.titleView = titleView;116 117 // 3.设置左右按钮118 vc.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImageName:@"top_navigation_menuicon" target:self action:@selector(leftMenuClick)];119 vc.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithImageName:@"top_navigation_infoicon" target:self action:@selector(rightMenuClick)];120 121 // 4.包装一个导航控制器122 HMNavigationController *nav = [[HMNavigationController alloc] initWithRootViewController:vc];123 // 让newsNav成为self(HMMainViewController)的子控制器,能保证:self在,newsNav就在124 // 如果两个控制器互为父子关系,那么它们的view也应该互为父子关系125 [self addChildViewController:nav];126 }127 128 #pragma mark - 监听导航栏按钮点击129 - (void)leftMenuClick130 {131 self.leftMenu.hidden = NO;132 self.rightMenuVc.view.hidden = YES;133 134 [UIView animateWithDuration:HMNavShowAnimDuration animations:^{135 // 取出正在显示的导航控制器的view136 UIView *showingView = self.showingNavigationController.view;137 138 // 缩放比例139 CGFloat navH = [UIScreen mainScreen].bounds.size.height - 2 * HMLeftMenuY;140 CGFloat scale = navH / [UIScreen mainScreen].bounds.size.height;141 142 // 菜单左边的间距143 CGFloat leftMenuMargin = [UIScreen mainScreen].bounds.size.width * (1 - scale) * 0.5;144 CGFloat translateX = HMLeftMenuW - leftMenuMargin;145 146 CGFloat topMargin = [UIScreen mainScreen].bounds.size.height * (1 - scale) * 0.5;147 CGFloat translateY = HMLeftMenuY - topMargin;148 149 // 缩放150 CGAffineTransform scaleForm = CGAffineTransformMakeScale(scale, scale);151 // 平移152 CGAffineTransform translateForm = CGAffineTransformTranslate(scaleForm, translateX / scale, translateY / scale);153 154 showingView.transform = translateForm;155 156 // 添加一个遮盖157 UIButton *cover = [[UIButton alloc] init];158 cover.tag = HMCoverTag;159 [cover addTarget:self action:@selector(coverClick:) forControlEvents:UIControlEventTouchUpInside];160 cover.frame = showingView.bounds;161 [showingView addSubview:cover];162 }];163 }164 165 - (void)coverClick:(UIView *)cover166 {167 [UIView animateWithDuration:HMNavShowAnimDuration animations:^{168 self.showingNavigationController.view.transform = CGAffineTransformIdentity;169 } completion:^(BOOL finished) {170 [cover removeFromSuperview];171 }];172 }173 174 - (void)rightMenuClick175 {176 self.leftMenu.hidden = YES;177 self.rightMenuVc.view.hidden = NO;178 179 [UIView animateWithDuration:HMNavShowAnimDuration animations:^{180 // 取出正在显示的导航控制器的view181 UIView *showingView = self.showingNavigationController.view;182 183 // 缩放比例184 CGFloat navH = [UIScreen mainScreen].bounds.size.height - 2 * HMLeftMenuY;185 CGFloat scale = navH / [UIScreen mainScreen].bounds.size.height;186 187 // 菜单左边的间距188 CGFloat leftMenuMargin = [UIScreen mainScreen].bounds.size.width * (1 - scale) * 0.5;189 CGFloat translateX = leftMenuMargin - self.rightMenuVc.view.width;190 191 CGFloat topMargin = [UIScreen mainScreen].bounds.size.height * (1 - scale) * 0.5;192 CGFloat translateY = HMLeftMenuY - topMargin;193 194 // 缩放195 CGAffineTransform scaleForm = CGAffineTransformMakeScale(scale, scale);196 // 平移197 CGAffineTransform translateForm = CGAffineTransformTranslate(scaleForm, translateX / scale, translateY / scale);198 199 showingView.transform = translateForm;200 201 // 添加一个遮盖202 UIButton *cover = [[UIButton alloc] init];203 cover.tag = HMCoverTag;204 [cover addTarget:self action:@selector(coverClick:) forControlEvents:UIControlEventTouchUpInside];205 cover.frame = showingView.bounds;206 [showingView addSubview:cover];207 } completion:^(BOOL finished) {208 [self.rightMenuVc didShow];209 }];210 }211 212 #pragma mark - HMLeftMenuDelegate213 - (void)leftMenu:(HMLeftMenu *)menu didSelectedButtonFromIndex:(int)fromIndex toIndex:(int)toIndex214 {215 // 0.移除旧控制器的view216 HMNavigationController *oldNav = self.childViewControllers[fromIndex];217 [oldNav.view removeFromSuperview];218 219 // 1.显示新控制器的view220 HMNavigationController *newNav = self.childViewControllers[toIndex];221 [self.view addSubview:newNav.view];222 223 // 2.设置新控制的transform跟旧控制器一样224 newNav.view.transform = oldNav.view.transform;225 // 设置阴影226 newNav.view.layer.shadowColor = [UIColor blackColor].CGColor;227 newNav.view.layer.shadowOffset = CGSizeMake(-3, 0);228 newNav.view.layer.shadowOpacity = 0.2;229 230 // 一个导航控制器的view第一次显示到它的父控件上时,如果transform的缩放值被改了,上面的20高度当时是不会出来231 232 // 2.设置当前正在显示的控制器233 self.showingNavigationController = newNav;234 235 // 3.点击遮盖236 [self coverClick:[newNav.view viewWithTag:HMCoverTag]];237 }238 @end
3:封装NAV导航控制器
1 #import "HMNavigationController.h" 2 #import "HMNavigationBar.h" 3 4 @interface HMNavigationController () 5 6 @end 7 8 @implementation HMNavigationController 9 10 + (void)initialize11 {12 UINavigationBar *appearance = [UINavigationBar appearance];13 14 // 设置导航栏背景15 [appearance setBackgroundImage:[UIImage imageNamed:@"top_navigation_background"] forBarMetrics:UIBarMetricsDefault];16 }17 18 - (void)viewDidLoad19 {20 [super viewDidLoad];21 22 // 替换为自定义的导航栏23 [self setValue:[[HMNavigationBar alloc] init] forKeyPath:@"navigationBar"];24 }25 26 #pragma mark - 这个方法也是专门用来布局子控件(当控制器的view尺寸发生改变的时候会调用)27 //- (void)viewDidLayoutSubviews28 //{29 // [super viewDidLayoutSubviews];30 // 31 // for (UIButton *button in self.navigationBar.subviews) {32 // if (![button isKindOfClass:[UIButton class]]) continue;33 //34 // if (button.centerX < self.navigationBar.width * 0.5) { // 左边的按钮35 // button.x = 0;36 // } else if (button.centerX > self.navigationBar.width * 0.5) { // 右边的按钮37 // button.x = self.view.width - button.width;38 // }39 // }40 //}41 42 @end
4:封装导航栏:目的是调整导航栏上左右item距离边框的位置.。左右按钮的背景图片,应该做成图片在中间,四周为镂空的图片
1 #import "HMNavigationBar.h" 2 3 @implementation HMNavigationBar 4 5 - (id)initWithFrame:(CGRect)frame 6 { 7 self = [super initWithFrame:frame]; 8 if (self) { 9 // Initialization code10 }11 return self;12 }13 14 - (void)layoutSubviews15 {16 [super layoutSubviews];17 18 for (UIButton *button in self.subviews) {19 if (![button isKindOfClass:[UIButton class]]) continue;20 21 if (button.centerX < self.width * 0.5) { // 左边的按钮22 button.x = 0;23 } else if (button.centerX > self.width * 0.5) { // 右边的按钮24 button.x = self.width - button.width;25 }26 }27 }28 @end
5:封装titleView:titleView由图片和文字构成,可以用button来实现,既可以设置图片也可以设置文字
1 #import2 3 @interface HMTitleView : UIButton4 @property (nonatomic, copy) NSString *title;5 @end
1 #import "HMTitleView.h" 2 3 @implementation HMTitleView 4 5 - (id)initWithFrame:(CGRect)frame 6 { 7 self = [super initWithFrame:frame]; 8 if (self) { 9 self.userInteractionEnabled = NO;10 [self setImage:[UIImage imageNamed:@"navbar_netease"] forState:UIControlStateNormal];11 [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];12 self.titleLabel.font = [UIFont boldSystemFontOfSize:22];13 self.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);14 self.height = self.currentImage.size.height;15 }16 return self;17 }18 19 - (void)setTitle:(NSString *)title20 {21 _title = [title copy];22 23 [self setTitle:title forState:UIControlStateNormal];24 25 NSDictionary *attrs = @{NSFontAttributeName : self.titleLabel.font};26 CGFloat titleW = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size.width;27 28 self.width = titleW + self.titleEdgeInsets.left + self.currentImage.size.width;29 }30 @end
6:封装item,uiview,image分类
1 #import2 3 @interface UIBarButtonItem (Extension)4 + (UIBarButtonItem *)itemWithImageName:(NSString *)imageName target:(id)target action:(SEL)action;5 @end
1 #import "UIBarButtonItem+Extension.h" 2 3 @implementation UIBarButtonItem (Extension) 4 + (UIBarButtonItem *)itemWithImageName:(NSString *)imageName target:(id)target action:(SEL)action 5 { 6 UIButton *button = [[UIButton alloc] init]; 7 [button setBackgroundImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; 8 9 // 设置按钮的尺寸为背景图片的尺寸10 button.size = button.currentBackgroundImage.size;11 12 // 监听按钮点击13 [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];14 return [[UIBarButtonItem alloc] initWithCustomView:button];15 }16 @end
1 #import2 3 @interface UIView (Extension) 4 @property (nonatomic, assign) CGFloat x; 5 @property (nonatomic, assign) CGFloat y; 6 @property (nonatomic, assign) CGFloat centerX; 7 @property (nonatomic, assign) CGFloat centerY; 8 @property (nonatomic, assign) CGFloat width; 9 @property (nonatomic, assign) CGFloat height;10 @property (nonatomic, assign) CGSize size;11 @end
1 #import "UIView+Extension.h" 2 3 @implementation UIView (Extension) 4 5 - (void)setX:(CGFloat)x 6 { 7 CGRect frame = self.frame; 8 frame.origin.x = x; 9 self.frame = frame;10 }11 12 - (CGFloat)x13 {14 return self.frame.origin.x;15 }16 17 - (void)setY:(CGFloat)y18 {19 CGRect frame = self.frame;20 frame.origin.y = y;21 self.frame = frame;22 }23 24 - (CGFloat)y25 {26 return self.frame.origin.y;27 }28 29 - (void)setCenterX:(CGFloat)centerX30 {31 CGPoint center = self.center;32 center.x = centerX;33 self.center = center;34 }35 36 - (CGFloat)centerX37 {38 return self.center.x;39 }40 41 - (void)setCenterY:(CGFloat)centerY42 {43 CGPoint center = self.center;44 center.y = centerY;45 self.center = center;46 }47 48 - (CGFloat)centerY49 {50 return self.center.y;51 }52 53 - (void)setWidth:(CGFloat)width54 {55 CGRect frame = self.frame;56 frame.size.width = width;57 self.frame = frame;58 }59 60 - (CGFloat)width61 {62 return self.frame.size.width;63 }64 65 - (void)setHeight:(CGFloat)height66 {67 CGRect frame = self.frame;68 frame.size.height = height;69 self.frame = frame;70 }71 72 - (CGFloat)height73 {74 return self.frame.size.height;75 }76 77 - (void)setSize:(CGSize)size78 {79 // self.width = size.width;80 // self.height = size.height;81 CGRect frame = self.frame;82 frame.size = size;83 self.frame = frame;84 }85 86 - (CGSize)size87 {88 return self.frame.size;89 }90 91 @end
1 #import2 3 @interface UIImage (Extension)4 + (UIImage *)imageWithColor:(UIColor *)color;5 @end
1 #import "UIImage+Extension.h" 2 3 @implementation UIImage (Extension) 4 + (UIImage *)imageWithColor:(UIColor *)color 5 { 6 CGFloat imageW = 100; 7 CGFloat imageH = 100; 8 // 1.开启基于位图的图形上下文 9 UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageW, imageH), NO, 0.0);10 11 // 2.画一个color颜色的矩形框12 [color set];13 UIRectFill(CGRectMake(0, 0, imageW, imageH));14 15 // 3.拿到图片16 UIImage *image = UIGraphicsGetImageFromCurrentImageContext();17 18 // 4.关闭上下文19 UIGraphicsEndImageContext();20 21 return image;22 }23 @end
7:封装左侧菜单
1 #import2 @class HMLeftMenu; 3 4 @protocol HMLeftMenuDelegate 5 @optional 6 - (void)leftMenu:(HMLeftMenu *)menu didSelectedButtonFromIndex:(int)fromIndex toIndex:(int)toIndex; 7 @end 8 9 @interface HMLeftMenu : UIView10 @property (nonatomic, weak) id delegate;11 @end
1 #import "HMLeftMenu.h" 2 #import "HMLeftMenuButton.h" 3 4 @interface HMLeftMenu() 5 @property (nonatomic, weak) HMLeftMenuButton *selectedButton; 6 @end 7 8 @implementation HMLeftMenu 9 10 #pragma mark - 初始化 11 - (id)initWithFrame:(CGRect)frame 12 { 13 self = [super initWithFrame:frame]; 14 if (self) { 15 self.backgroundColor = [UIColor clearColor]; 16 17 CGFloat alpha = 0.2; 18 19 [self setupBtnWithIcon:@"sidebar_nav_news" title:@"新闻" bgColor:HMColorRGBA(202, 68, 73, alpha)]; 20 [self setupBtnWithIcon:@"sidebar_nav_reading" title:@"订阅" bgColor:HMColorRGBA(190, 111, 69, alpha)]; 21 [self setupBtnWithIcon:@"sidebar_nav_photo" title:@"图片" bgColor:HMColorRGBA(76, 132, 190, alpha)]; 22 [self setupBtnWithIcon:@"sidebar_nav_video" title:@"视频" bgColor:HMColorRGBA(101, 170, 78, alpha)]; 23 [self setupBtnWithIcon:@"sidebar_nav_comment" title:@"跟帖" bgColor:HMColorRGBA(170, 172, 73, alpha)]; 24 [self setupBtnWithIcon:@"sidebar_nav_radio" title:@"电台" bgColor:HMColorRGBA(190, 62, 119, alpha)]; 25 } 26 return self; 27 } 28 29 - (void)setDelegate:(id)delegate 30 { 31 _delegate = delegate; 32 33 // 默认选中新闻按钮 34 [self buttonClick:[self.subviews firstObject]]; 35 // [self buttonClick:self.subviews[1]]; 36 } 37 38 /** 39 * 添加按钮 40 * 41 * @param icon 图标 42 * @param title 标题 43 */ 44 - (HMLeftMenuButton *)setupBtnWithIcon:(NSString *)icon title:(NSString *)title bgColor:(UIColor *)bgColor 45 { 46 HMLeftMenuButton *btn = [[HMLeftMenuButton alloc] init]; 47 btn.tag = self.subviews.count; 48 [btn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown]; 49 [self addSubview:btn]; 50 51 // 设置图片和文字 52 [btn setImage:[UIImage imageNamed:icon] forState:UIControlStateNormal]; 53 [btn setTitle:title forState:UIControlStateNormal]; 54 [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 55 btn.titleLabel.font = [UIFont systemFontOfSize:17]; 56 57 // 设置按钮选中的背景 58 [btn setBackgroundImage:[UIImage imageWithColor:bgColor] forState:UIControlStateSelected]; 59 60 // 设置高亮的时候不要让图标变色 61 btn.adjustsImageWhenHighlighted = NO; 62 63 // 设置按钮的内容左对齐 64 btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 65 66 // 设置间距 67 btn.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0); 68 btn.contentEdgeInsets = UIEdgeInsetsMake(0, 30, 0, 0); 69 70 return btn; 71 } 72 73 - (void)layoutSubviews 74 { 75 [super layoutSubviews]; 76 77 // 设置按钮的frame 78 int btnCount = self.subviews.count; 79 CGFloat btnW = self.width; 80 CGFloat btnH = self.height / btnCount; 81 for (int i = 0; i
8:封装右侧菜单
1 #import2 3 @interface HMRightMenuController : UIViewController4 /**5 * 右边菜单全部显示出来6 */7 - (void)didShow;8 @end
1 #import "HMRightMenuController.h" 2 #import "HMRightMenuCenterViewRow.h" 3 4 @interface HMRightMenuController () 5 @property (weak, nonatomic) IBOutlet UIImageView *iconView; 6 @property (weak, nonatomic) IBOutlet UIView *centerView; 7 @property (weak, nonatomic) IBOutlet UIView *bottomView; 8 @end 9 10 @implementation HMRightMenuController11 - (void)viewDidLoad12 {13 [super viewDidLoad];14 15 // 1.填充中间的内容16 [self setupCenterView];17 18 // 2.填充底部的内容19 [self setupBottomView];20 }21 22 /**23 * 填充中间的内容24 */25 - (void)setupCenterView26 {27 HMRightMenuCenterViewRow *row =[self setupCenterViewRow:@"商城 能赚能花,土豪当家" icon:@"promoboard_icon_mall"];28 [self setupCenterViewRow:@"活动 4.0发布会粉丝招募" icon:@"promoboard_icon_activities"];29 [self setupCenterViewRow:@"应用 金币从来都是这送的" icon:@"promoboard_icon_apps"];30 31 self.centerView.height = self.centerView.subviews.count * row.height;32 }33 34 - (HMRightMenuCenterViewRow *)setupCenterViewRow:(NSString *)title icon:(NSString *)icon35 {36 HMRightMenuCenterViewRow *row = [HMRightMenuCenterViewRow centerViewRow];37 row.icon = icon;38 row.title = title;39 row.y = row.height * self.centerView.subviews.count;40 [self.centerView addSubview:row];41 return row;42 }43 44 /**45 * 填充底部的内容46 */47 - (void)setupBottomView48 {49 50 }51 52 - (void)didShow53 {54 // 让头像旋转55 // [UIView animateWithDuration:1.0 animations:^{56 // self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);57 // } completion:^(BOOL finished) {58 // self.iconView.image = [UIImage imageNamed:@"user_defaultgift"];59 // 60 // [UIView animateWithDuration:1.0 animations:^{61 // self.iconView.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);62 // }];63 // }];64 // CATransition65 // CATransition *anim = [CATransition animation];66 // anim.duration = 1.0;67 // anim.type = @"rippleEffect";68 // [self.iconView.layer addAnimation:anim forKey:nil];69 70 [UIView transitionWithView:self.iconView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{71 self.iconView.image = [UIImage imageNamed:@"user_defaultgift"];72 } completion:^(BOOL finished) {73 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{74 [UIView transitionWithView:self.iconView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{75 self.iconView.image = [UIImage imageNamed:@"default_avatar"];76 } completion:nil];77 });78 }];79 }80 81 @end
1 #import2 3 @interface HMRightMenuCenterViewRow : UIView4 + (instancetype)centerViewRow;5 6 @property (nonatomic, copy) NSString *icon;7 @property (nonatomic, copy) NSString *title;8 @end
1 #import "HMRightMenuCenterViewRow.h" 2 3 @interface HMRightMenuCenterViewRow() 4 @property (weak, nonatomic) IBOutlet UIButton *titleView; 5 @property (weak, nonatomic) IBOutlet UIImageView *iconView; 6 @end 7 8 @implementation HMRightMenuCenterViewRow 9 + (instancetype)centerViewRow10 {11 return [[[NSBundle mainBundle] loadNibNamed:@"HMRightMenuCenterViewRow" owner:nil options:nil] lastObject];12 }13 14 - (void)setIcon:(NSString *)icon15 {16 _icon = [icon copy];17 18 self.iconView.image = [UIImage imageNamed:icon];19 }20 21 - (void)setTitle:(NSString *)title22 {23 _title = [title copy];24 25 [self.titleView setTitle:title forState:UIControlStateNormal];26 }27 @end
三:知识点总结:
1:启动图的广告展示界面:1:创建启动图展示控制器,其中广告的图片一般是从服务器获取,搞个定时器,GCD延迟函数,经过一段时间后,再切换窗口的根视图控制器为主控制器。 UIWindow *window = [UIApplication sharedApplication].keyWindow;keyWindow为主窗口,负责键盘处理和文本框输入事件,若是textView,textField不能处理-输入事件,或是响应键盘则判断当前显示窗口是否是主窗口keyWindow。2:其中还可以通过keyWindow获取rootViewController,和当前显示的导航控制器,keyWindow.rootViewController, TabBarVC *tab = keyWindow.rootViewController; NAV *nav = tab.selecteViewcontroller;得到当前显示的导航控制器,nav.viewControllers,得到当前导航控制器栈里的所有控制器。
2:sattic const 定义常量来代替宏定义: static const CGFloat HMNavShowAnimDuration = 0.25;来代替 #define HMNavShowAnimDuration 0.25 ,因为static const定义的常量在系统中只会开辟一份内存,而#define,所定义的每一个常量都会开辟一份临时的内存空间。用static修饰的全局变量,只能是全局变量,该变量才会限制在本类中使用,外部不可以访问,若不加static,则用ertern,就可以在其他类中访问该变量。const在前在后都是一样的,定义字符串变量时,static NSString * const name = @"name";则指针name不可改变。const修饰变量或是常量时,就看const右侧是什么,则const右侧的指针或是变量不可改变。
3:创建子控制器addChildViewController:苹果官方建议当控制器互为父子关系时,控制器上的view也应该为父子关系。1:将创建子控制器的代码封装起来,创建子控制器对象,将子控制对象和title作为参数传入。2:titleView的封装:1:因为titleView为图片和文字构成,所以用button去封装titleView,创建控件继承UIButton,设置自身属性,btn的ennable,或是userenable为NO,titleLable.font,titleColor,setImage,btn.adjustImageWhenHeighlight(当setImage时),titleEdgeInsets,imageEdgeInset,contentEdgeInset,继承UIcontrol的contentHorizanAliment(整个btn文本的对其方式),btn的高度,self.height =self.currentImage.size.height;self.currentImage获得当前的image,btn.currentBackgroundImage,获得背景图片 2:懒加载子控件,添加到父视图上,无 3:layoutSubView布局子控件 4:向外界提供model接口,重写model的set方法,外界提供title接口,重写title的set方法,btn要设置自身的宽度自适应,用boundingRectWithSize,如下:
NSDictionary *attrs = @{NSFontAttributeName : self.titleLabel.font}; CGFloat titleW = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size.width; self.width = titleW + self.titleEdgeInsets.left + self.currentImage.size.width;
其中,只要赋值,就调用set方法,想获得此变量,就调用get方法,没必要再UIFont去设置,boundingRectWithSize,单行绘制文本时,两个参数都穿MAXFLOAT,基于基线绘制NSStringDrawingUsesLineFragmentOrigin,若是多行,则先设置lable.numberoflines = 0;再限制宽度或是高度,参数采用基线绘制,NSStringDrawingUsesLineFragmentOrigin,和行间距 NSStringDrawingUsesFontLeading。总的宽度就为,image的宽度+self.titleEdgeInsets.left+self.currentImage.size.width。其中titleEdgeInsets的设置,指的是距离左侧图片的距离,为正数,则指的是右侧距离
4:自定义导航栏上的左右item,自定义btn,btn setBackgroundImage,图片为按钮的背景图片,btn的大小为图片的大小, button.size = button.currentBackgroundImage.size;
5:封装导航控制器:1:继承系统导航控制器,因为设置全局导航栏的属性,只需设置一次就好,所以写在+ (void)initialize里,该方法只在该方法所在类第一个方法被调用之前被调用一次,只在整个项目中只会调用一次。先获得全局导航栏,item对象,利用settitleTextAttribute forState属性,可以设置不同状态下的属性 2:左右item距离屏幕左右边框的距离很大,想要调整,1:可遍历系统控件的子控件,找出左右按钮,再设置左右按钮的frame 2:自定义bar用kvc代替系统的bar:新建类继承系统的bar,在layoutSubView方法中,则子类继承了系统bar的属性,遍历子控件数组,self.subViews,在遍历时,要做条件过滤,不符合条件的直接return,或是continue。找到子控件的时候停止遍历,做性能优化。找到左右按钮后,判断左右按钮的btn的center与中点比较,看是哪个左右item。3:设置完frame之后,再在封装的nav控制器中创建对象,setValue forKeyPath ,kvc来代替系统的控件,第二个参数,就是nav控制器下属性定义的navBar,调用此方法,得是某个控制器下的某个属性
// 替换为自定义的导航栏 [self setValue:[[HMNavigationBar alloc] init] forKeyPath:@"navigationBar"];4:其中:layoutSubView方法只适用于在UIView中,在控制器中调整子控件可以重写系统方法:- (void)viewDidLayoutSubviews,但是不要忘记调用super
6:[self addChildViewController:nav];1:添加子控制器,能则父控制器就对子控制器有一个强引用,只要父控制器在,则子控制器就在,而且控制器互为父子关系,则他们的view也应该互为父子关系。2:子控制器数组:self.childViewControllers,得到子控制器数组,只读,子控制器从父控制器移除,subNav removeFromParentViewController ,获得父控制器:subNav.parentViewController
7:封装左侧菜单:1:有背景的话可以继承UIImageView,但要开启用户交互权限,也可以继承UIView,设置背景图片时,添加UIImageView,或是view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:]];,平铺图片,或有间隔线,或是调用drawInRect,画上一张图片 2:先设置自身的属性,clearcolor 3:懒加载控件,设置控件属性,添加到父视图上,创建相同的控件,例如button,可以采用for循环创建,也可以一个一个创建,传title,image,枚举tag值或是其他参数,封装一个button,创建对象,setImage,btn.adjust,setBackgroudImage,可以设枚举tag值,也可以通过设置self.subViews.count为tag值,也可以设置titleEdgeInset,ImageEdgeInset,contentEdgeInset,继承UIcontrol的也可以用contentHorizanAliment(文本的对齐方式),在layoutSubView里设置控件的frame,1:属性,成员变量 ,通过tag值取出,若是有多个子控件,可以设置tag值,遍历子控件数组,通过tag值将子控件取出2:放在大数组里,从数组里取出,若是又有button又有其他控件,则两两分别放在数组里,分别从数组里取出,设置frame 3:遍历subView,从subViews的数组里取出。4:设置按钮的回调:1:可通过协议代理,通知 ,block ,协议代理,block适用于层级较浅的回调,通知,多播委托适用于层级较深的结构 2 :若是监听系统的控件:继承UIControl的可以addTarget,可以系统的代理,系统通知,子类若没有查看父类,也可以重写系统的方法,不要忘记调用super方法,来实现监听 3:按钮的协议代理,传枚举tag值是为了在控制器实现监听点击,传fromIndex,传toIndex,是为了从数组取出旧的移除,并添加新的 4:按钮的回调方法,两个按钮状态的判断,btn.selected = !btn.isSelected,三个按钮切换状态则用按钮三部曲,若是传index则把代理方法放前面 5:设置按钮默认选中:1:直接设哪个按钮被选中,再设seletedBtn 2:返回按钮,调用按钮的点击方法,要考虑需不需要重写代理的setDelegate方法在该方法中设置按钮的默认选中。
8:transform属性:1:当点击左上角按钮的时候,先进行缩放,在进行平移,在缩放的基础上进行平移,求缩放比例:缩放后的高度 = 屏幕高度 - 上下间距 ,用缩放的高度与原高度的比值就是缩放比例,在UIView的动画中先进行缩放,再在缩放的基础上进行平移,平移的距离,1-缩放比例,就为剩下的长度比例,0.5倍,就是缩放后的view的实际距屏宽度。2:在动画结束的时候设置一个遮盖效果,遮盖效果:1:可以为一个view,添加手势,2:也可以另遮盖为一个button,监听button的点击事件,button在此处不能为成员变量,button的点击事件中,动画先将transform清空,完成时,将button从父视图移除。3:监听点击事件:1:继承UIControl的可以addTarget 2:添加手势监听器 3:实现touch beagn,touch end,touch cancle 方法,配合UITouch,使用,UITouch *touch = [UITouch anyObject]; touch.view可以获得触摸点点击的view,CGPoint point = [touch locationInView:touch.view];此方法可获得触摸点,其中触摸点的是基于touch.view来计算的,如果此参数填父视图view,则是基于整个父视图来计算的。然后一般是遍历数组,做条件过滤,利用CGRectContainPoint方法,根据触摸点求出矩形框的rect,找到结果后停止遍历 4:transform是二维旋转,view的图层layer是三维动画,view.layer.transform = CAAFfitransform(,,,,);最后三个参数为xyz轴,若是010,则是绕着y轴上1点与原点连线的的向量旋转,第一个参数为旋转的角度。5:动画效果:1:二维动画:UIView + transform 2:三维动画:UIView +view.layer.transform = CAAFi ,注意三个参数 3:转场动画:也就是翻转动画,[UIView transition...];翻转动画有各种参数值 4:三维动画也可以用CATranstion,CATranstion *ad = [CATranstion animation];ad.duration 动画时间,ad.type,动画的方式,字符串,[self.iconaImageView.layer addAnimation: ad forkey:nil];
9:监听左侧菜单按钮的回调事件:效果是,点击左侧按钮,切换视图,动画清空transform。将旧的控制器取出,view从父视图上移除,再将新控制器取出,将新控制器的view添加到父视图上,此时可以不必设置新view的frame,默认为父视图的bounds。将旧控制器的transform赋值给新的控制器的transform,更新当前的控制器,动画回去,此时就是清空新控制器的transform,相当于点击了旧控制器的遮盖,将按钮从父视图上取出,调用按钮点击方法。
10:在使用xib绘制界面的时候,有时明明尺寸设置正确,但是就不能正常显示,1:此时可以禁用autoLayout 2:setNeedsLayOut ,layOutIfNeed配合使用,异步调用layoutSubView,重新计算尺寸。3:当xib加载完毕后会调用awakeFromNib,在此方法中可以设置xib中控件的一些属性,当xib中已经设置了控件的尺寸,在外部依然可以修改xib中控件的尺寸
11:右侧菜单的封装设计:1:对于控制器和view来说,要采取分层封装的思想,就是将view和或是控制器切分成一个个模块,将零散的控件封装在一个整体内,然后再考虑整个项目中其他地方有没有用到,若用到则考虑继承关心A继承B,或是B继承A,或是将AB公共部分抽成父类C,AB分别继承父类C,不同的部分在AB中单独实现 2:右侧的菜单封装,可以采取三种封装方法:1:看成是一个tableView,table的headerView,tableView,table的footerView 但是没有cell的复用,且按钮的回调监听,太复杂 2:还可以考虑封装一个大view,再将上中下封装为三个小view添加到大view上,但是同样涉及的问题就是按钮的监听回调太麻烦 3:考虑用一个控制器,在控制器内实现按钮的监听,在控制器内再将整体封装为上中下三个view。2:对于顶部view的封装以及动画,顶部view中的头像的翻转就用转场动画,每执行一次转场动画,转360度,并更换图片,动画完成时,执行GCD延迟函数,在执行一个转场动画转回来,再更改frame 3:中间View的封装,按钮会点亮,调用的是button的btn.showTouchWhenHeighlight。此方法若是button有图片,则只在button的图片处点亮,再将每一行封装为一个View,点图片和箭头都会亮,则其肯定为一个整体,所以可以考虑button为整个背景,将图片和箭头添加到button上,因为当点击图片和箭头时,默认没有开启用户的交互权限,通过的事件的传递可以找到触摸点所在的view,但是该view不能处理事件,则事件会又子控件传递给父控件去处理,也就是交给button去处理,buttonn能处理所以点击图片箭头都会被点亮 4:设置每个封装view的y值,view.y = self.subViews.count *height;总高度,self.subViews.count *height