创建工程
添加第三方RESideMenu
添加PCH文件Starry.pch
在程序Build Settings 的Prefix Header 写上$(SRCROOT)/工程名称/Starry.pch
Starry.pch
#ifndef Starry_pch
#define Starry_pch
/*
常用头文件的导入
*/
#import "BaseViewController.h"
#import "AppDelegate.h"
#define App_Delegate (AppDelegate *)[UIApplication sharedApplication].delegate
/*
系统版本号
*/
#define VERSION_10_0 [UIDevice currentDevice].systemVersion.doubleValue >= 10.0
#define VERSION_9_0 [UIDevice currentDevice].systemVersion.doubleValue >= 9.0
/*
用于适配的宏
*/
#define SCR_W [UIScreen mainScreen].bounds.size.width
#define SCR_H [UIScreen mainScreen].bounds.size.height
//适配x轴的宏
#define FIT_X(w) (SCR_W / 375. *(w))
//适配Y轴的宏
#define FIT_Y(h) (SCR_H / 667. *(h))
/*
当前app版本号的宏
*/
#define VERSION_CURRENT [[NSBundle mainBundle].infoDictionary objectForKey:@"CFBundleShortVersionString"]
//持久化当前版本号的key的宏
#define NOT_FIRST_LANUCH @"NotFirstLanuch"
/*
Doucuments目录的宏
*/
#define DOCUMENT_PATH [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
#endif /* Starry_pch */
AppDelegate.h
#import
#import
#import "RESideMenu.h" // 抽屉视图第三方
@interface AppDelegate : UIResponder
@property (nonatomic,strong)RESideMenu *sideMenu;
@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong) NSPersistentContainer *persistentContainer;
- (void)saveContext;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "LeftMenuViewController.h"
#import "NewsViewController.h"
#import "WeatherViewController.h"
#import "LiveShowViewController.h"
@interface AppDelegate ()
@property (nonatomic,strong)UITabBarController *tabBarCtl;//标签栏控制器
@property (nonatomic,strong)LeftMenuViewController *leftVC;//左侧菜单控制器
@end
@implementation AppDelegate
#pragma mark - 私有方法
//私有方法,用于生成一个导航控制器
- (UINavigationController *)createNavigationWithController:(UIViewController *)vc title:(NSString *)title image:(NSString *)imgName selectImage:(NSString *)selectImgName{
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
vc.navigationItem.title = title;
nav.tabBarItem = [[UITabBarItem alloc]initWithTitle:title image:[UIImage imageNamed:imgName] selectedImage:[UIImage imageNamed:selectImgName]];
return nav;
}
#pragma mark-侧滑控制器
//左侧菜单
- (LeftMenuViewController *)leftVC{
if (!_leftVC) {
_leftVC = [[LeftMenuViewController alloc]init];
}
return _leftVC;
}
//标签栏控制器
- (UITabBarController *)tabBarCtl{
if (!_tabBarCtl) {
_tabBarCtl = [[UITabBarController alloc]init];
UINavigationController *newsNav = [self createNavigationWithController:[[NewsViewController alloc]init] title:@"新闻头条" image:@"TabBar_home_1" selectImage:@"TabBar_home_2"];
UINavigationController *weatherNav = [self createNavigationWithController:[[WeatherViewController alloc]init] title:@"墨迹天气" image:@"TabBar_dynamic_1" selectImage:@"TabBar_dynamic_2"];
UINavigationController *liveNav = [self createNavigationWithController:[[LiveShowViewController alloc]init] title:@"直播" image:@"TabBar_public_1" selectImage:@"TabBar_public_2"];
_tabBarCtl.viewControllers = @[newsNav,weatherNav,liveNav];
}
return _tabBarCtl;
}
- (RESideMenu *)sideMenu{
if (!_sideMenu) {
_sideMenu = [[RESideMenu alloc]initWithContentViewController:self.tabBarCtl leftMenuViewController:self.leftVC rightMenuViewController:nil];
_sideMenu.backgroundImage = [UIImage imageNamed:@"Stars"];
_sideMenu.scaleContentView = NO;//设置内容视图不可缩放
_sideMenu.contentViewInPortraitOffsetCenterX = FIT_X(100);
}
return _sideMenu;
}
#pragma mark- UIApplicationDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
GuideViewController *guideVC = [[GuideViewController alloc]init];
//第一次运行app
if (![[NSUserDefaults standardUserDefaults]objectForKey:NOT_FIRST_LANUCH]) {
self.window.rootViewController = guideVC;
}
//非首次运行app
else{
//获取当前的版本号
//获取持久化的版本号数据
NSString *savedVersion = [[NSUserDefaults standardUserDefaults]objectForKey:NOT_FIRST_LANUCH];
//判断版本号是否一致
if ([savedVersion isEqualToString:VERSION_CURRENT]) {
//没有更新
self.window.rootViewController = self.sideMenu;
}
else{
//更新了
self.window.rootViewController = guideVC;
}
}
return YES;
}
引导页控制器------
第三方引导页ImageScrollView.h
#import
/// 表示图片滚动视图的样式
typedef enum {
ImageScrollType_Guide = 100, // 开机guide视图样式
ImageScrollType_Banner // banner栏样式
}ImageScrollType;
/// 协议,触发事件回调的方法
@protocol ImageScrollViewDelegate
@optional
/// “guide”样式的最后一个视图上的“立即体验”按钮触发
-(void)experienceDidHandle;
/// “banner”样式每一个图片触发回调的方法;index表示选中的图片的下标
-(void)bannerImageDidHandleWithIndex:(NSInteger)index;
@end
@interface ImageScrollView : UIScrollView
/// 参数1:滚动视图位置(建议以4.7寸屏设置); 参数2:样式 ; 参数3:图片名称数组 ; 参数4:guide样式的“立即体验”按钮标题;参数5:字体颜色 参数6:guide样式的“立即体验”按钮位置;参数7:banner轮播图时间间隔 ; 参数8:代理设置,用于触发事件回调
-(instancetype)initWithFrame:(CGRect)frame
style:(ImageScrollType)type
images:(NSArray *)imgNameArr
confirmBtnTitle:(NSString *)title
confirmBtnTitleColor:(UIColor *)titleColor
confirmBtnFrame:(CGRect)btnFrame
autoScrollTimeInterval:(NSTimeInterval)interval
delegate:(id)delegate;
/// 给ImageScrollView的父视图添加分页控件,必须把ImageScrollView加为父视图的子视图之后再调用方法
-(void)addPageControlToSuperView:(UIView *)superView;
@end
ImageScrollView.m
#import "ImageScrollView.h"
#define SCR_W [UIScreen mainScreen].bounds.size.width // 屏幕宽度
#define SCR_H [UIScreen mainScreen].bounds.size.height // 屏幕高度
#define FIT_X(x) (SCR_W/375.*(x)) // 用于x轴适配
#define FIT_Y(y) (SCR_H/667.*(y)) // 用于y轴适配
@interface ImageScrollView ()
{
ImageScrollType _type; // 样式
NSString *_confirmBtnTitle; // 确认按钮标题
CGRect _confirmBtnFrame; // 确认按钮位置
UIColor *_confirmBtnTitleColor; // 确认按钮标题颜色
NSUInteger _imgCount; // 图片个数
CGFloat _disX; //在X轴的移动距离
}
@property(nonatomic,assign)idscDelegate;
@property(nonatomic,strong)NSTimer *myTimer; // 定时器
@property(nonatomic,strong)UIPageControl *pageCtl; // 分页控件
@end
@implementation ImageScrollView
#pragma mark - 对外接口
/// 实例化方法
-(instancetype)initWithFrame:(CGRect)frame
style:(ImageScrollType)type
images:(NSArray *)imgNameArr
confirmBtnTitle:(NSString *)title
confirmBtnTitleColor:(UIColor *)titleColor
confirmBtnFrame:(CGRect)btnFrame
autoScrollTimeInterval:(NSTimeInterval)interval
delegate:(id)delegate {
self = [super initWithFrame:frame];
if (self) {
if (type == ImageScrollType_Guide)
{
// 设置内容视图大小
self.contentSize = CGSizeMake(frame.size.width * imgNameArr.count, frame.size.height);
}
else
{
// 设置内容视图大小
self.contentSize = CGSizeMake(frame.size.width * (imgNameArr.count+2), frame.size.height);
}
// 样式赋值
_type = type;
// 图片数量赋值
_imgCount = imgNameArr.count;
// guide样式固定大小
if (type == ImageScrollType_Guide) {
self.frame = CGRectMake(0, 0, SCR_W, SCR_H);
self.contentSize = CGSizeMake(SCR_W * imgNameArr.count, SCR_H);
_confirmBtnTitle = title;
_confirmBtnFrame = btnFrame;
_confirmBtnTitleColor = titleColor;
}
// 隐藏滚动条
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
// 开启分页属性
self.pagingEnabled = YES;
// 设置UIScrollView代理
self.delegate = self;
// 设置自定义的代理
self.scDelegate = delegate;
// 添加图片子视图
[self addImageSubViews:imgNameArr];
// 添加定时器
if(type == ImageScrollType_Banner) {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(timerDidHandle:) userInfo:nil repeats:YES];
}
}
return self;
}
/// 添加分页控件方法
-(void)addPageControlToSuperView:(UIView *)superView {
[superView addSubview:self.pageCtl];
}
#pragma mark - 分页控制器实例化getter重写
/// 添加分页子视图
-(UIPageControl *)pageCtl{
if (!_pageCtl) {
_pageCtl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, FIT_X(300), FIT_Y(25))];
if (_type == ImageScrollType_Guide)
{
_pageCtl.center = CGPointMake(SCR_W/2, SCR_H-FIT_Y(30));
}
else{
_pageCtl.center = CGPointMake(self.frame.origin.x + self.frame.size.width/2, self.frame.origin.y + self.frame.size.height-FIT_Y(25));
}
_pageCtl.pageIndicatorTintColor = [UIColor grayColor];
_pageCtl.currentPageIndicatorTintColor = [UIColor redColor];
_pageCtl.hidesForSinglePage = YES;
_pageCtl.numberOfPages = _imgCount;
_pageCtl.currentPage = 0;
}
return _pageCtl;
}
#pragma mark - 添加图片子视图
/// 添加图片子视图
-(void)addImageSubViews:(NSArray *)imgNameArr {
if (_type == ImageScrollType_Guide)
{
for (int i = 0; i
GuideViewController.h
#import
@interface GuideViewController : UIViewController
@end
GuideViewController.m
#import "GuideViewController.h"
#import "ImageScrollView.h"
#import "AppDelegate.h"
@interface GuideViewController ()
@end
@implementation GuideViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *arr = @[@"guidePage1",@"guidePage2",@"guidePage3"];
ImageScrollView *imgScrView = [[ImageScrollView alloc]initWithFrame:self.view.frame style:ImageScrollType_Guide images:arr confirmBtnTitle:@"立即体验" confirmBtnTitleColor:[UIColor whiteColor] confirmBtnFrame:CGRectMake(FIT_X(260), FIT_Y(30), FIT_X(120), FIT_Y(40)) autoScrollTimeInterval:0.0 delegate:self];
[self.view addSubview:imgScrView];
[imgScrView addPageControlToSuperView:self.view];
}
#pragma mark -ImageScrollViewDelegate
- (void)experienceDidHandle{
//获取当前的版本号,持久化
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:VERSION_CURRENT forKey:NOT_FIRST_LANUCH];
[ud synchronize];
//切换窗口的根视图控制器
AppDelegate *app = App_Delegate;
app.window.rootViewController = app.sideMenu;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
LeftMenuViewController.h
#import
@interface LeftMenuViewController : UIViewController
@end
LeftMenuViewController.m
#import "LeftMenuViewController.h"
#import "LoginViewController.h"
@interface LeftMenuViewController ()
{
NSArray *_tableDatas;//表格数据
}
//头像视图
@property(nonatomic,strong)UIImageView *headImgView;
//账号lable
@property(nonatomic,strong)UILabel *accountLable;
//表格
@property(nonatomic,strong)UITableView *table;
//登录控制器
@property (nonatomic,strong)LoginViewController *loginVC;
@end
@implementation LeftMenuViewController
#pragma mark - 控制器实例化
//登录控制器
- (LoginViewController *)loginVC{
if (!_loginVC) {
_loginVC = [[LoginViewController alloc]init];
}
return _loginVC;
}
#pragma mark- 控件实例化
//头像视图
- (UIImageView *)headImgView{
if (!_headImgView) {
_headImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, FIT_X(80), FIT_Y(80))];
_headImgView.center = CGPointMake(SCR_W/4+FIT_X(50), FIT_Y(104));
_headImgView.clipsToBounds = YES;
_headImgView.layer.cornerRadius = FIT_X(40);
_headImgView.image = [UIImage imageNamed:@"40"];
_headImgView.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(headImgDidHandle:)];
[_headImgView addGestureRecognizer:tap];
}
return _headImgView;
}
//账号标签
- (UILabel *)accountLable{
if (!_accountLable) {
_accountLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, FIT_X(300), FIT_Y(30))];
_accountLable.center = CGPointMake(self.headImgView.center.x, self.headImgView.center.y + self.headImgView.frame.size.height / 2 +FIT_Y(15)+FIT_Y(20));
_accountLable.text = @"17744534890";
_accountLable.textAlignment = NSTextAlignmentCenter;
_accountLable.textColor = [UIColor whiteColor];
_accountLable.font = [UIFont systemFontOfSize:18.0];
}
return _accountLable;
}
//表格
- (UITableView *)table{
if (!_table) {
_table = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, FIT_X(300), 200) style:UITableViewStylePlain];
_table.rowHeight = 50;
_table.center = CGPointMake(self.headImgView.center.x, self.accountLable.center.y + self.accountLable.frame.size.height / 2 + 100 +FIT_Y(60));
_table.dataSource = self;
_table.delegate = self;
_table.scrollEnabled = NO;
_table.backgroundColor = [UIColor clearColor];
}
return _table;
}
#pragma mark-UITableViewDataSource
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _tableDatas.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = _tableDatas[indexPath.row];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont systemFontOfSize:18.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#pragma mark -触发事件
//头像点击触发事件
- (void)headImgDidHandle:(id)sender{
[self presentViewController:self.loginVC animated:YES completion:nil];
}
#pragma mark- loadView
- (void)loadView{
[super loadView];
[self.view addSubview:self.headImgView];
[self.view addSubview:self.accountLable];
[self.view addSubview:self.table];
}
#pragma mark
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_tableDatas = @[@"个人信息",@"我的收藏",@"关于我们",@"退出登录"];
[_table reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
NewsViewController.h
#import
@interface NewsViewController : BaseViewController
@end
NewsViewController.m
#import "NewsViewController.h"
@interface NewsViewController ()
@end
@implementation NewsViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor yellowColor];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
WeatherViewController.h
#import
@interface WeatherViewController : BaseViewController
@end
WeatherViewController.m
#import "WeatherViewController.h"
@interface WeatherViewController ()
@end
@implementation WeatherViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
LiveShowViewController.h
#import
@interface LiveShowViewController : BaseViewController
@end
LiveShowViewController.m
#import "LiveShowViewController.h"
@interface LiveShowViewController ()
@end
@implementation LiveShowViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end