博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网易新闻侧滑抽屉效果(利用父子控制器实现)
阅读量:4962 次
发布时间:2019-06-12

本文共 29483 字,大约阅读时间需要 98 分钟。

一:类似于网易的抽屉效果,启动有广告,进入主界面后,点击左上角按钮,侧滑左抽屉,点击右上角,侧滑出右抽屉。点击左抽屉按钮,对视图进行切换

 

 二代码:

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 #import 
2 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 #import 
2 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 #import 
2 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 #import 
2 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 #import 
2 @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 #import 
2 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 #import 
2 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

 

转载于:https://www.cnblogs.com/cqb-learner/p/5724434.html

你可能感兴趣的文章
在vmware上安装kali系统
查看>>
Jmeter 基本介绍
查看>>
java实现栈
查看>>
JavaScript
查看>>
spring的controller默认是单例还是多例
查看>>
ROI
查看>>
PostgreSQL学习手册
查看>>
课后习题
查看>>
[题解]Yet Another Subarray Problem-DP 、思维(codeforces 1197D)
查看>>
RecyclerView下拉加载集合越界问题
查看>>
Trunk 实现跨交换机 VLAN 通信
查看>>
吴恩达教你如何学习机器学习
查看>>
常用的PCB库文件
查看>>
Javascript模块化编程 require.js使用详解
查看>>
快速幂学习入门
查看>>
ubuntu 刚更改默认python3版本后更新包等
查看>>
quartz教程三
查看>>
利用saltstack初始化OpenStack服务器环境
查看>>
python连接数据库并插入数据
查看>>
Log4net使用笔记
查看>>