iOS开发教程之微博骨架搭建

2020-01-12 13:29:54王振洲
本文是IOS开发教程的第四篇,主要讲诉如何一步步搭建起微博的骨架,并附上源码,希望对大家的IOS开发能提供些借鉴  

最终效果图:

iOS开发教程之微博骨架搭建

BeyondViewController.m


//
// BeyondViewController.m
// 20_帅哥no微博
//
// Created by beyond on 14-8-3.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// 这个就是主控制器,分为两块,下面是Dock栏,上面是显示不同的子控制器的view,子控制器最好用导航控制器包装一下,这样子控制器就自带了导航条,左按钮,标题,右按钮

/*
 无法点击,或点击 无响应的原因:
 userInteractionEnabled = NO;
 hidden = YES
 alpha <= 0.01
 clearColor ,view的颜色为透明,不可以被点击
 */

#import "BeyondViewController.h"
#import "Dock.h"
#import "DockBtn.h"
#import "Column.h"
// 主控制器下面Dock的高度
#define kDockHeight 44
@interface BeyondViewController ()
{
  // 从plist中加载 的栏目对象数组
  NSMutableArray *_columns;
  
  // 主控制器下方的Dock选项栏
  Dock *_dock;
  
  // 记录当前选中的子控制器,目的是将其view从父控制器的view中移除,为添加新的子控制器的view做准备
  UIViewController *_currentChildVC;
}
@end

@implementation BeyondViewController

- (BOOL)prefersStatusBarHidden
{
  return NO;
  
}

- (void)viewDidLoad
{
  [super viewDidLoad];

  // 0.从plist加载 栏目数组,遍历数组,根据字典,生成一个一个栏目对象,存入栏目对象数组中
  _columns = [NSMutableArray array];
  NSBundle *mainBundle = [NSBundle mainBundle];
  NSString *fullPath = [mainBundle pathForResource:@"ColumnList.plist" ofType:nil];
  NSArray *arr = [NSArray arrayWithContentsOfFile:fullPath];
  
  for (NSDictionary *dict in arr) {
    Column *column = [Column columnWithDict:dict];
    [_columns addObject:column];
  }
  // 1.添加dock到主控制器方的下方
  [self addDock];
  
  // 2.一次性创建所有的子控制器,并用导航包装后,添加到当前控制器的childViewControllers
  [self createAllChildViewControllers];
  
  // 3.默认选中第0个控制器
  [self changeChildViewAtIndex:0 andChildVCClassName:@"HomeViewController"];
  
  // 4.一次性设置全局的导航栏上面的颜色主题样式
  [self setGlobalNavigationItemColorTheme];
  
}
#pragma mark 添加dock
- (void)addDock
{
  // 1.添加dock到主控制器方的下方
  _dock = [[Dock alloc] init];
  
  // 2.监听Dock内部Btn的点击,让控制器成为dock的代理属性,或者,为dock的成员blok赋值
  __unsafe_unretained BeyondViewController *beyond = self;
  _dock.btnClickBlock = ^(DockBtn *btn)
  {
    // 调用自定义方法,更改子视图,参数1:索引号,参数2:子控制器的类名
    [beyond changeChildViewAtIndex:btn.tag andChildVCClassName:btn.viewControllerClassName];
  };
  
  
  // 3,设置Dock的frame
  _dock.frame = CGRectMake(0, self.view.frame.size.height - kDockHeight, self.view.frame.size.width, kDockHeight);
  log(@"_dock frame--%@",NSStringFromCGRect(_dock.frame));
  // 4,添加dock到主控制器方的view
  [self.view addSubview:_dock];
  
  // 2.遍历column对象数组,批量添加dock里面的DockBtn
  for (Column *column in _columns) {
    [_dock addDockBtnWithIconName:column.columnImgName title:column.columnName viewControllerClassName:column.columnClassName];
  }
  
  // 3.设置dock默认选中第0个
  [_dock setDockBtnClickedAtIndex:0];
  
}
// 自定义方法,更改子视图,参数1:索引号,参数2:子控制器的类名
- (void)changeChildViewAtIndex:(int)index andChildVCClassName:(NSString *)viewControllerClassName
{
  log(@"点击了 %@",viewControllerClassName);
  if (self.childViewControllers.count > 0) {
    // 0,先取出新的子控制器,如果 新的子控制器就是当前的这个控制器,直接返回 好吗?
    UIViewController *childVC = [self childViewControllers][index];
    if (childVC == _currentChildVC) return ;
    // 1,先移除先前的子控制器的view
    [_currentChildVC.view removeFromSuperview];
    
    // 2,添加新的子控制器的view到主控制器的view
    
    childVC.view.frame = CGRectMake(0, 20, 320, 416);
    //log(@"self view --%@",NSStringFromCGRect(self.view.frame));
    //log(@"childVC view --%@",NSStringFromCGRect(childVC.view.frame));
    // 不会重复添加view,因为一旦发现重复添加某个view,就会将它置于最上面,最好是,先移除旧的view,再添加新的view
    [self.view addSubview:childVC.view  ];
    
    // 3,重要,必须更新当前的子控制器,为下次移除做准备
    _currentChildVC = childVC;
  }
}

#pragma mark 创建所有的子控制器(一共5个,首面,消息,我,广场,更多)
- (void)createAllChildViewControllers
{
  // 1.遍历栏目对象数组,批量创建所有的子控制器,并用导航控制器包装,最后添加到self childViewControllers数组中保存
  for (Column *column in _columns) {
    Class c = NSClassFromString(column.columnClassName);
    UIViewController *childVC =nil;
    if ([NSStringFromClass(c) isEqualToString:@"MoreViewController"]) {
      // 特别注意:在继承了tableView之后,要想再使用group样式,必须在创建的时候指定样式为group,这儿特别指的是moreViewController
      childVC = [[c alloc]initWithStyle:UITableViewStyleGrouped];
    } else {
      childVC = [[c alloc]init];
    }
    // 设置导航栏的标题
    childVC.navigationItem.title = column.columnName;
    // 重写父类的方法
    [self addChildViewController:childVC];
  }
}
#pragma marck - 重写父类的方法
// 为了在添加子控制器时,全部包装成一个个导航控制器,所以重写addChildViewController方法
- (void)addChildViewController:(UIViewController *)childVC
{
  UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:childVC];
  // 将包装成导航控制器的子控制器添加到主控制器中,这样每一个子控制器就拥有自己的特有的导航条了
  [super addChildViewController:nav];
}


// 4.一次性设置全局的导航栏上面的颜色主题样式
- (void)setGlobalNavigationItemColorTheme
{
  // 1.导航栏
  // 1.1.操作navBar相当操作整个应用中的所有导航栏
  UINavigationBar *navBar = [UINavigationBar appearance];
  
  // 1.2.设置导航栏UINavigationBar的背景图片(拉伸)
  [navBar setBackgroundImage:[UIImage imageStretchedWithName:@"navigationbar_background.png"] forBarMetrics:UIBarMetricsDefault];
  // 1.3.设置状态栏背景,没有效果???
  [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
  
  
  // 1.4.设置导航栏UINavigationBar的Title文字属性,通过字典 设置
  NSMutableDictionary *navigationBarTitleDict = [NSMutableDictionary dictionary];
  // 前景色,即文字的颜色
  [navigationBarTitleDict setObject:[UIColor darkGrayColor] forKey:NSForegroundColorAttributeName];
  // 文字阴影取消,字典中不能放结构体,要用NSValue包装一下
  [navigationBarTitleDict setObject:[NSValue valueWithUIOffset:UIOffsetZero] forKey:NSShadowAttributeName];
  
  
  // 2.导航栏上面的item
  UIBarButtonItem *barBtnItem =[UIBarButtonItem appearance];
  // 2.1.设置背景
  // 按钮正常状态时侯的背景
  [barBtnItem setBackgroundImage:[UIImage imageNamed:@"navigationbar_button_background.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
  // 按钮高亮状态时侯的背景
  [barBtnItem setBackgroundImage:[UIImage imageNamed:@"navigationbar_button_background_pushed.png"] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
  // 按钮未选中状态时侯的背景
  [barBtnItem setBackgroundImage:[UIImage imageNamed:@"navigationbar_button_background_disable.png"] forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault];
  
  
  // 2.2.设置barBtnItem的文字属性
  NSMutableDictionary *barItemTitleDict = [NSMutableDictionary dictionary];
  // barItemDict的文字颜色
  [barItemTitleDict setValue:[UIColor darkGrayColor] forKey:NSForegroundColorAttributeName];
  // barItemDict的字体
  [barItemTitleDict setValue:[UIFont systemFontOfSize:13] forKey:NSFontAttributeName];
  
  // 2.3.用字典 设置barBtnItem的标题文字属性
  [barBtnItem setTitleTextAttributes:barItemTitleDict forState:UIControlStateNormal];
  [barBtnItem setTitleTextAttributes:barItemTitleDict forState:UIControlStateHighlighted];
}
@end