一 基本搭建
main->UIApplicationMain底層實現
- 1.創建UIApplication對象
- 2.創建UIApplication對象代理
- 3.開啓主運行循環,保持程序一直運行
- 4.加載info.plist文件,判斷下是否指定main
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- 手動創建 storyboard
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1.創建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 2.創建窗口的跟控制器
// 創建tabBarVc
UITabBarController *tabBarVc = [[UITabBarController alloc] init];
// 設置窗口的根控制器
self.window.rootViewController = tabBarVc;
// 3.讓窗口顯示
[self.window makeKeyAndVisible];
return YES;
}
二 自定義 tabBar
#pragma mark - 添加所有子控制器
- (void)setUpAllChildViewController
{
// 購彩大廳
XMGHallViewController *hall = [[XMGHallViewController alloc] init];
hall.view.backgroundColor = [UIColor redColor];
// 添加一個子控制器
[self setUpOneChildViewController:hall image:[UIImage imageNamed:@"TabBar_LotteryHall_new"] selImage:[UIImage imageNamed:@"TabBar_LotteryHall_selected_new"]];
// 競技場
XMGArenaViewController *arena = [[XMGArenaViewController alloc] init];
arena.view.backgroundColor = [UIColor purpleColor];
[self setUpOneChildViewController:arena image:[UIImage imageNamed:@"TabBar_Arena_new"] selImage:[UIImage imageNamed:@"TabBar_Arena_selected_new"]];
……
- 抽取相似方法代碼
#pragma mark - 添加一個子控件
- (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selImage:(UIImage *)selImage
{
// 設置tabBarButton的圖片,tabBarButton的內容由對應的子控制器的tabBarItem
vc.tabBarItem.image = image;
vc.tabBarItem.selectedImage = selImage;
[self addChildViewController:vc];
}
- 自定義tabBar
#pragma mark - 自定義tabBar
- (void)setUpTabBar
{
// 1.移除系統的tabBar,移除系統自帶的tabBarButton
[self.tabBar removeFromSuperview];
// 2.添加自己的tabBar
XMGTabBar *tabBar = [[XMGTabBar alloc] init];
tabBar.delegate = self;
// tabBar按鈕的個數,由tabBar子控制器個數決定
// tabBar.count = (int)self.childViewControllers.count;
// 傳對應子控制器的tabBarItem數組
tabBar.items = self.items;
tabBar.backgroundColor = [UIColor greenColor];
tabBar.frame = self.tabBar.frame;
[self.view addSubview:tabBar];
}
- 封裝自定義tabBar
- (void)setItems:(NSArray *)items
{
_items = items;
for (UITabBarItem *item in items) {
UIButton *btn = [XMGTabBarButton buttonWithType:UIButtonTypeCustom];
// 設置內容
[btn setBackgroundImage:item.image forState:UIControlStateNormal];
[btn setBackgroundImage:item.selectedImage forState:UIControlStateSelected];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
btn.tag = self.subviews.count;
if (self.subviews.count == 0) {
[self btnClick:btn];
}
[self addSubview:btn];
}
}
- 每次選中一個邏輯
- (void)btnClick:(UIButton *)btn
{
_selBtn.selected = NO;
btn.selected = YES;
_selBtn = btn;
// 通知代理點擊了哪個角標的按鈕
if ([_delegate respondsToSelector:@selector(tabBar:didClickBtn:)]) {
[_delegate tabBar:self didClickBtn:btn.tag];
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
int count = (int)self.subviews.count;
CGFloat btnW = self.bounds.size.width / count;
CGFloat btnH = self.bounds.size.height;
CGFloat btnY = 0;
CGFloat btnX = 0;
// 佈局按鈕的位置
for (int i = 0; i < count; i++) {
UIButton *btn = self.subviews[i];
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
}
}
- 按鈕取消高亮狀態
- 自定義按鈕 XMGTabBarButton
- (void)setHighlighted:(BOOL)highlighted
{
}
- 點擊 button 通知代理切換控制器 view
@class XMGTabBar;
@protocol XMGTabBarDelgate <NSObject>
@optional
- (void)tabBar:(XMGTabBar *)tabBar didClickBtn:(NSInteger)index;
@end
@interface XMGTabBar : UIView
/** items:UITabBarItem模型 */
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, weak) id<XMGTabBarDelgate> delegate;
@end
- 仿系統實現 tabBar 代理方法
#pragma mark -XMGTabBarDelgate方法
// 當點擊tabBar上的條的時候調用
- (void)tabBar:(XMGTabBar *)tabBar didClickBtn:(NSInteger)index
{
// 切換界面
self.selectedIndex = index;
}
三 設置導航條內容
#pragma mark - 添加一個子控制器,並且設置對應的內容
- (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selImage:(UIImage *)selImage title:(NSString *)title
{
// 設置導航條
vc.navigationItem.title = title;
// 設置tabBarButton的圖片,tabBarButton的內容由對應的子控制器的tabBarItem
vc.tabBarItem.image = image;
vc.tabBarItem.selectedImage = selImage;
// 保存對應子控制器的UITabBarItem
[self.items addObject:vc.tabBarItem];
// 如果想要一個控制器既展示自己的view,同時想增加一個導航條,直接包裝成導航控制器
// 包裝成導航控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
// 設置導航條背景圖片,必須填UIBarMetricsDefault
// 使用UIBarMetricsDefault,導航控制器的子控制器view的尺寸不包括導航條部分
[nav.navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
// 設置導航條文字顏色
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 設置顏色
dict[NSForegroundColorAttributeName] = [UIColor whiteColor];
dict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:22];
[nav.navigationBar setTitleTextAttributes:dict];
[self addChildViewController:nav];
}
四 自定義導航控制器
- initialize方法(初始化一次)
- 創建了5個導航控制器,會創建5次,需要只設置一次
// 當前類或者它的子類第一次使用的時候調用
// 初始化一個類
+ (void)initialize
{
// 設置導航條的背景,文字顏色
// 誰用我的導航控制器,只設置使用自己導航控制器下的導航條
// 獲取整個app裏所有導航條外觀的標誌(通常開發不用,強制性大)
// UINavigationBar *bar = [UINavigationBar appearance];
// 獲取當前類下的導航條
// self指向->XMGNavigationController
UINavigationBar *bar = [UINavigationBar appearanceWhenContainedIn:self, nil];
// Do any additional setup after loading the view.
// 設置導航條背景圖片,必須填UIBarMetricsDefault
// 使用UIBarMetricsDefault,導航控制器的子控制器view的尺寸不包括導航條部分
[bar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
// 設置導航條文字顏色
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 設置顏色
dict[NSForegroundColorAttributeName] = [UIColor whiteColor];
dict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:22];
[bar setTitleTextAttributes:dict];
}
五 導航條TabBar item設置
- 購彩大廳左側圖標
- (void)viewDidLoad {
[super viewDidLoad];
// 不讓圖片被渲染封裝方法
UIImage *image = [UIImage imageWithOriginRenderingName:@"CS50_activity_image"];
// 原始代碼如下:
// UIImage *image = [UIImage imageNamed:@"CS50_activity_image"];
// image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 設置導航條左邊按鈕
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStyleDone target:self action:@selector(activity)];
}
- 圖片不被渲染分類方法 UIImage+Image.h
+ (instancetype)imageWithOriginRenderingName:(NSString *)imageName
{
UIImage *image = [UIImage imageNamed:imageName];
return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
- 蒙板效果XMGCover
#define XMGKeyWindow [UIApplication sharedApplication].keyWindow
+ (void)show
{
XMGCover *cover = [[self alloc] init];
cover.frame = XMGKeyWindow.bounds;
cover.backgroundColor = [UIColor blackColor];
cover.alpha = 0.5;
// 獲取主窗口
[XMGKeyWindow addSubview:cover];
}
+ (void)hide
{
// 隱藏蒙板
for (UIView *childView in XMGKeyWindow.subviews) {
if ([childView isKindOfClass:self]) { // 是蒙板
[childView removeFromSuperview];
}
}
}
// 點擊活動按鈕的時候調用
- (void)activity
{
// 彈出蒙板,
// 只要以後想要把一個控件顯示在最外邊,就添加到窗口,提供一個show方法
[XMGCover show];
// 彈出pop菜單
XMGPopMenu *menu = [XMGPopMenu showInPoint:self.view.center];
menu.delegate = self;
}
#pragma mark - XMGPopMenuDelegate
// 點擊菜單上關閉按鈕的時候就會調用
- (void)popMenuDidClickCloseMenu:(XMGPopMenu *)menu
{
[UIView animateWithDuration:0 animations:nil completion:^(BOOL finished) {
}];
// 定義移動完成的block,保存移動完成的代碼
void (^completion)() = ^{
// 當移動完成的時候,把蒙板消失
[XMGCover hide];
};
// block精髓:可以當做參數去用。
// 菜單移動到某個位置,並且縮放。
[menu hideInPoint:CGPointMake(44, 44) completion:completion];
}
- 用代理監聽關閉按鈕
- (IBAction)close:(id)sender {
// 通知代理做事情,告訴代理點擊了關閉
if ([_delegate respondsToSelector:@selector(popMenuDidClickCloseMenu:)]) {
[_delegate popMenuDidClickCloseMenu:self];
}
}
// 隱藏
- (void)hideInPoint:(CGPoint)point completion:(void (^)())completion
{
[UIView animateWithDuration:.5 animations:^{
self.center = point;
// 直接修改父控件的尺寸,是不會影響子控件
// self.bounds = CGRectMake(0, 0, 1, 1);
// 如果設置0,控件直接縮放爲0,沒有動畫,如果想要動畫,搞一個最小值
self.transform = CGAffineTransformMakeScale(0.01, 0.01);
} completion:^(BOOL finished) {
[self removeFromSuperview];
if (completion) {
completion();
}
}];
}
- 實現代理方法
#pragma mark - XMGPopMenuDelegate
// 點擊菜單上關閉按鈕的時候就會調用
- (void)popMenuDidClickCloseMenu:(XMGPopMenu *)menu
{
[UIView animateWithDuration:0 animations:nil completion:^(BOOL finished) {
}];
// 定義移動完成的block,保存移動完成的代碼
void (^completion)() = ^{
// 當移動完成的時候,把蒙板消失
[XMGCover hide];
};
// 菜單移動到某個位置,並且縮放。
[menu hideInPoint:CGPointMake(44, 44) completion:completion];
}
六 block
- 定義 block
- void(^)() : block類型
void(^block)() = ^(){
// 保存代碼
};
- 起別名
// name: block類型的別名
typedef void(^MyBlock)();
// 調用block,纔會執行block裏面代碼
block();
七 抽取 UIView分類
- pch 文件
- 存儲一些公用的宏,公用的分類
設置 pch 路徑
#ifdef __OBJC__
#define XMGKeyWindow [UIApplication sharedApplication].keyWindow
#import "UIImage+Image.h"
#import "UIView+Frame.h"
#endif
- UIView+Frame.h 分類
@property在分類裏面只會自動生成get,set方法,並不會生成下劃線的成員屬性
- 封裝寬、高、x、y
- (CGFloat)width
{
return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width
{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
…… ……