以下是我初学UI后的简单综合练习.
gif图镇楼
Untitled.gif这是市面上常见的app的三级视图模式
使用到了
UINavigationController
UITableView
UITabBarController
这三种.其中UITabBarController , UINavigationController暂时不使用系统原生的,我将其经行了子类化.
细说之前我先表明立场,本人不提倡完全使用nib(xib)文件和storyboard文件直接创建viewController中的View.推荐使用代码创建各种View,方便维护.当然,两者相互结合,取长补短我是支持的.
要实现以上 app 的视图模式,大致思路如下:
step 1 Window创建
首先在appdelegate中建一个Window. 它的rootVC是一个子类化的UITabBarController.
step 2 自定义TabBar
step 2.1
你需要子类化一个UITabBarController,以实现 '选中底图' 的滑动动画(就是那个半透明的黑色方块).我暂时不使用UITabBarController自带的TabBar,而自己用一个imageView作为代替
step 2.2
既然使用自定义的UITabBarController替代TabBar,那么点击事件一定要实现,并且要有几个button,配上相应的图标
step 2.3
每个图标对应一个view,同时又要有navigation.所以,先让每一个button对应一个navigation,再使'navigation.view'添加用户需要的view.这样方便push & pop 操作
step 3 第一个view中的UITableView
可见,我在第一个view中放入了一个表视图,有头视图,具体的点击事件暂时没有实现.
step 4 头视图的scrollView
很多app种都有可拖动的头视图,并且可以点击进入一个页面.我们需要在headerView中添加各一个scrollView和pageControl. scrollView和pageControl两者关联. 并且在scrollView中添加几个imageView(需要单手指手势)供用户点击.最后push进入一个页面
step 5 TabBar何时隐藏
TabBar仅仅是用户在第一个界面才会使用的东西,所以在用户push到其他页面时,需要隐藏,pop回来的时候需要显示.其中的实现有很多方法,但是都挺费脑的.笔者笨笨的,学了半天.╮(╯_╰)╭
上代码了!!!
这里是AppDelegate
//
// AppDelegate.m
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/3.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import "AppDelegate.h"
#import "TabBarController_custom.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//创建window
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
//-------------------------------------------
TabBarController_custom *TBCtrl_custom = [[TabBarController_custom alloc] init];
self.window.rootViewController = TBCtrl_custom;
// Override point for customization after application launch.
return YES;
}
@end
自定义的tabBarController
//
// TabBarController_custom.m
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/3.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import "TabBarController_custom.h"
#import "NavigationController_custom.h"
#import "home_ViewController.h"
#import "discover_ViewController.h"
#import "message_ViewController.h"
#import "profile_ViewController.h"
#define screenWidth [UIScreen mainScreen].bounds.size.width
#define screenHeight [UIScreen mainScreen].bounds.size.height
@interface TabBarController_custom ()
{
UIImageView *background_custom;
UIImageView *selectImage;
NSArray *VCs;
}
@end
@implementation TabBarController_custom
- (void)viewDidLoad {
[super viewDidLoad];
//自定义UI
[self createUI];
//
[self createVCs];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//-------------------------------------------
//自定义的UI效果实现
- (void)createUI {
//隐藏系统的tabBar
self.tabBar.hidden = YES;
//自定义tabBar的背景
background_custom = [[UIImageView alloc] initWithFrame:CGRectMake(0, screenHeight - 49, screenWidth, 49)];
background_custom.image = [UIImage imageNamed:@"tabbar_bg"];
//响应手势
background_custom.userInteractionEnabled = YES;
//自定义Item
NSArray *titles = @[@"主页", @"发现", @"消息", @"个人中心"];
//这里的title仅仅控制tabBar 的 item 上的文字
NSArray *imgName_Array = @[@"tabbar_home", @"tabbar_discover", @"tabbar_message", @"tabbar_profile"];
//-------------------------------------------
for (int i = 0; i < titles.count; i++) {
//自定义创建button
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
NSLog(@"i = %d >> %p", i, btn);
//设置不同状态的图片
[btn setImage:[UIImage imageNamed:imgName_Array[i]] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@_highlighted",imgName_Array[i]]] forState:UIControlStateHighlighted];
//设置button的位置
btn.frame = CGRectMake(i * screenWidth / titles.count, 0, screenWidth/titles.count, 30);
//标记button
btn.tag = i;
//设置button的title
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(i * screenWidth / titles.count, 27, screenWidth/titles.count, 19)];
label.text = titles[i];
label.textColor = [UIColor lightGrayColor];
label.textAlignment = 1;
label.font = [UIFont systemFontOfSize:12.0];
[btn addTarget:self action:@selector(buttonAC:) forControlEvents:UIControlEventTouchUpInside];
//加载button到自定义UI
[background_custom addSubview:label];
[background_custom addSubview:btn];
/*
label & button
0,1 2,3 4,5 6,7
*/
}
//-------------------------------------------
//取出subview中的buttonView.
NSArray *subviews = background_custom.subviews;
UIButton *temp = subviews[1];
//设置选中底图
selectImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"selected"]];
selectImage.alpha = 0.5;//底图透明度
selectImage.center = CGPointMake(temp.center.x, temp.center.y + 9);//合适的位置,按照中心对其
[background_custom addSubview:selectImage];
[self.view addSubview:background_custom];
}
- (void)createVCs {
home_ViewController *homeView = [[home_ViewController alloc] init];
discover_ViewController *discoverView = [[discover_ViewController alloc] init];
message_ViewController *messageView = [[message_ViewController alloc] init];
profile_ViewController *profileView = [[profile_ViewController alloc] init];
//方便后面的subView访问最初的视图,我加了一个mainSuperView 属性,并且仅仅设为assign.
homeView.mainSuperView = (UIView *)self;
discoverView.mainSuperView = (UIView *)self;
messageView.mainSuperView = (UIView *)self;
profileView.mainSuperView = (UIView *)self;
NavigationController_custom *homeNavigationCtrl = [[NavigationController_custom alloc] initWithRootViewController:homeView];
NavigationController_custom *discoverNavigationCtrl = [[NavigationController_custom alloc] initWithRootViewController:discoverView];
NavigationController_custom *messageNavigationCtrl = [[NavigationController_custom alloc] initWithRootViewController:messageView];
NavigationController_custom *profileNavigationCtrl = [[NavigationController_custom alloc] initWithRootViewController:profileView];
VCs = @[homeNavigationCtrl, discoverNavigationCtrl, messageNavigationCtrl, profileNavigationCtrl];
self.viewControllers = VCs;
self.selectedIndex = 0;
}
- (void)buttonAC:(UIButton *)button {
//.选择底图点击跟随.
[UIView animateWithDuration:0.25 animations:^{
selectImage.center = CGPointMake(button.center.x, button.center.y + 9);
}];
if (button.tag == 0) {
self.selectedIndex = 0;
}else if (button.tag == 1) {
self.selectedIndex = 1;
}else if (button.tag == 2) {
self.selectedIndex = 2;
}else if (button.tag == 3) {
self.selectedIndex = 3;
}
}
- (void)ctrl_hidden_custom_tabBar {
if (background_custom.hidden == 0) {
[UIView animateWithDuration:0.4 animations:^{
background_custom.alpha = 0;
} completion:^(BOOL finished) {
background_custom.hidden = 1;
}];
}else {
background_custom.hidden = 0;
[UIView animateWithDuration:0.4 animations:^{
background_custom.alpha = 1;
}];
}
}
//-------------------------------------------
@end
这里是第一个viewController的.h
//
// home_ViewController.h
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/3.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface home_ViewController : UIViewController
@property (nonatomic,assign) UIView *mainSuperView;
//为了.m中方便访问最开始的tabBarController,我自定义了一个属性
@end
//
// home_ViewController.m
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/3.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import "home_ViewController.h"
#import "TabBarController_custom.h"
#import "subViewController.h"
#define S_width [UIScreen mainScreen].bounds.size.width
#define S_height [UIScreen mainScreen].bounds.size.height
@interface home_ViewController () <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate, subVC_protocol>
{
//tableView的文本array
NSMutableArray *_textArray;
// tableView 属性
UITableView *_tableView_main;
// scrollView 属性
UIScrollView *_scrollView;
// pageControl 属性
UIPageControl *_pageControl;
}
@end
@implementation home_ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view .backgroundColor = [UIColor redColor];
self.title = @"主页";
//-------------------------------------------
//准备工作
_textArray = [[NSMutableArray alloc] initWithCapacity:1];
for (int i = 0; i < 16; i++) {
NSString *text00 = [NSString stringWithFormat:@"row%03i",i];
[_textArray addObject:text00];
}
NSLog(@"textArray:%@",_textArray);
//创建tableView
_tableView_main = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, S_width, S_height) style:UITableViewStylePlain];
//设置 tableView 的 源 & 代理
_tableView_main.dataSource = self;
_tableView_main.delegate = self;
//设置头视图------------------------------------------------------------------
_tableView_main.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, S_width, S_width / 16 * 9)];
//准备工作
NSArray *imgArray = @[
@"ty00.jpg",
@"ty01.jpg",
@"ty02.jpg",
@"ty03.jpg",
@"ty04.jpg"
];
//创建scrollView
UIScrollView *s_headerView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, S_width, S_width / 16 * 9)];
//设置内容页大小
s_headerView.contentSize = CGSizeMake(S_width * imgArray.count, S_width / 16 * 9);
//设置背景色
s_headerView.backgroundColor = [UIColor blackColor];
//滑条
s_headerView.showsHorizontalScrollIndicator = NO;
s_headerView.showsVerticalScrollIndicator = NO;
//分页
s_headerView.pagingEnabled = YES;
//反弹
s_headerView.bounces = YES;
//scroll代理
s_headerView.delegate = self;
//添加内容
for (int i = 0; i < imgArray.count; i++) {
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imgArray[i]]];
imgView.frame = CGRectMake(i * S_width, 0, S_width, S_width / 16 * 9);
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.tag = i;
imgView.userInteractionEnabled = YES;
//给imageView 添加单手指点击事件
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap_click:)];
[imgView addGestureRecognizer:singleTap];
[s_headerView addSubview:imgView];
}
//添加到view
[_tableView_main.tableHeaderView addSubview:s_headerView];
//-------------------------------------------
//创建pageControl
_pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(40, S_width / 16 * 9 - 30, S_width - 80, 20)];
//点总数
_pageControl.numberOfPages = imgArray.count;
//当前选中的点
_pageControl.currentPage = 0;
//点的颜色
_pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
//选中点的颜色
_pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
//添加到view
[_tableView_main.tableHeaderView addSubview:_pageControl];
//----------------------------------------------------------------------
//添加到view
[self.view addSubview:_tableView_main];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//--------------dataSource-------------------
#pragma mark dataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _textArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//ID创建
static NSString *cellID = @"cellID";
//如果可以,请求可复用的cell
UITableViewCell *cell = [_tableView_main dequeueReusableCellWithIdentifier:cellID];
//cell为空,创建cell
if (cell == nil) {
NSLog(@"调用创建!!");
//创建cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
//内容设置
cell.textLabel.text = _textArray[indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:15];
return cell;
}
//--------------------------scrollViewDelegate-----------------
#pragma mark scrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[UIView animateWithDuration:0.1 animations:^{
NSInteger zz = scrollView.contentOffset.x / S_width;
NSLog(@"动画");
_pageControl.currentPage = zz;
}];
}
-(void)singleTap_click:(UIGestureRecognizer *)gestureRecognizer {
UIImageView *imageView = (UIImageView *)[gestureRecognizer view];
[self pushSubVC_img:imageView];
}
- (void)pushSubVC_img:(UIImageView *)img {
subViewController *subVC = [[subViewController alloc] initWithDelegate:self];
[self giveSubVC:subVC TagOfImageView:img];
[self.navigationController pushViewController:subVC animated:YES];
[(TabBarController_custom *)self.mainSuperView ctrl_hidden_custom_tabBar];
}
//----------------------------subVC_protocol---------------
- (void)giveSubVC:(subViewController *)subVC TagOfImageView:(UIImageView*)imageView {
[subVC setTagOfImg:(imageView.tag)];
}
@end
模拟的第一个push进去的view,是有协议的哦!
//
// subViewController.h
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/5.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import <UIKit/UIKit.h>
@class subViewController;
@protocol subVC_protocol <NSObject> //拟定协议,待class执行
- (void)giveSubVC:(subViewController *)subVC TagOfImageView:(UIImageView*)imageView;
@end
//-------------------------------------------
@interface subViewController : UIViewController
{
@public
NSInteger _tagOfImg;
}
@property (nonatomic,assign) id <subVC_protocol> delegate;
- (void)setTagOfImg:(NSInteger)tagOfImg;
- (instancetype)initWithDelegate:(id <subVC_protocol>)delegate;
@end
//
// subViewController.m
// UITabbar_custom
//
// Created by Gavin Guan on 16/5/5.
// Copyright © 2016年 Gavin Guan. All rights reserved.
//
#import "subViewController.h"
#import "TabBarController_custom.h"
@interface subViewController ()
@end
@implementation subViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"设置图片之前");
UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"ty%02li.jpg", (long)_tagOfImg]];
UIImageView *imageView00 = [[UIImageView alloc] initWithImage:img];
imageView00.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width - 64);
imageView00.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:imageView00];
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
// leftButton.backgroundColor = [UIColor redColor];
[leftButton setTitle:@"返回" forState:UIControlStateNormal];
[leftButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[leftButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
leftButton.frame = CGRectMake(0, 0, 40, 20);
[leftButton addTarget:self action:@selector(buttonAC:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
self.navigationItem.leftBarButtonItem = leftButtonItem;
NSLog(@"视图加载完成");
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//-------------------------------------------
- (instancetype)initWithDelegate:(id <subVC_protocol>)delegate {
self = [super init];
if (self) {
self.delegate = delegate;
}
return self;
}
- (void)setTagOfImg:(NSInteger)tagOfImg {
_tagOfImg = tagOfImg;
}
//-------------------------------------------
- (void)buttonAC:(UIButton *)button {
NSLog(@"button");
[self.navigationController popViewControllerAnimated:YES];
//不仅仅要pop当前页面,还要把tabBar再次显示出来
if (self.navigationController.viewControllers.count == 1) {
UIView *rootVC = (UIView *)self.navigationController.viewControllers[0];
UIView *mainSuperView = [rootVC valueForKey:@"mainSuperView"];
[(TabBarController_custom *)mainSuperView performSelector:@selector(ctrl_hidden_custom_tabBar)];
}
}
@end
最后我发现,你写代码之初是不会考虑到以后一些事情的,到时候再改是很麻烦的,所以如果可以,最好一些类直接子类化自定义,以免麻烦.
╮(╯_╰)╭