软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 移动开发 -> 百思不得姐框架(二) -> 正文阅读

[移动开发]百思不得姐框架(二)


一 该部分框架效果图和实现思路

框架二的效果图:


[img]http://img.blog.csdn.net/20160403215612487

实现思路:

—- 1> 先完善tabBar(主要是自定义)
—- 2> 再完善导航条
—- 3> 其次完善屏幕侧滑(主要是全屏侧滑功能)

二 抽取分类(设置到插件中)

1 抽取分类的思想: 实现复用

—-> 1.1 上部分代码中,我们需要设置tabBar中图片成未被渲染的格式,因此我们抽取了一个分类,用分类里面的方法实现了效果.
—-> 分类代码:
//传入一张图片的名称返回一张未被渲染的图片
+ (UIImage *)originalWithImage:(NSString *)imageName
{
    UIImage *image = [UIImage imageNamed:imageName];

    return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

2 问题:虽然抽取了分类,但是我们是不是想在用分类设置图片的时候,也能有插件提示功能呢?

设置插件功能图:(图一)

[img]http://img.blog.csdn.net/20160403220503897

具体的设置思路:<—>见下图

2.1 按住option,点击桌面的左上角,找到前往,点击资源库
图一:

[img]http://img.blog.csdn.net/20160403220717726
图二:

[img]http://img.blog.csdn.net/20160403220750663
图三:

[img]http://img.blog.csdn.net/20160403220811585
图四:

[img]http://img.blog.csdn.net/20160403220835070
图五:

[img]http://img.blog.csdn.net/20160403220903914
图六:

[img]http://img.blog.csdn.net/20160403220932898
图七:

[img]http://img.blog.csdn.net/20160403220958961

最后:找到插件的位置,具体做法就是先command + c 然后command + v 赋值个item,然后将图七中的改为自己的分类方法就可以.

三 问题一

1 问题: 选中的图片中,配图的文字被渲染了(图片不被渲染我们用分类解决了)
2 实现思路:
—-> 1> 通过获取到全局的tabBar
—-> 2> 再通过字典来包装设置字体颜色和字体的大小
3 在自定义的tabBarController控制器中设置选中字体的颜色不被渲染(全程序只需要设置一次)–>选中状态
4 通过拿到全局的tabBarItem去设置按钮的字体大小(由整个app的效果图知道,字体需要加粗)

具体代码:

#pragma mark - 设置标题的字体不被渲染(该方法全程序只会来一次)
+ (void)load
{
    //获取全局的tabBar
    UITabBarItem *tabBar = [UITabBarItem appearance];
    //创建可变字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    //设置文字的颜色
    dict[NSegroundColorAttributeName] = [UIColor blackColor];
    //设置字体
    [tabBar setTitleTextAttributes:dict forState:UIControlStateSelected];
    NSMutableDictionary *dict1 = [NSMutableDictionary dictionary];
    //设置文字的大小
    dict1[NSFontAttributeName] = [UIFont boldSystemFontOfSize:13];
    //设置字体大小
    [tabBar setTitleTextAttributes:dict1 forState:UIControlStateNormal];
}
5 发布按钮显示不出来—>发布按钮的图片比较大,显示出来就会有问题
—-> 5.1 让正常状态下的图片也不被渲染(能达到效果)
nav2.tabBarItem.image = [UIImage originalWithImage:@"tabBar_publish_icon"];
—-> 5.2 设置对应的控制器的tabBarItem,通过设置图片的内边距来实现(通过测试也不符合条件:原因是选中时候高亮,但是不选中的时候就会恢复状态)–>很明显是高亮状态
publish.tabBarItem.imageInsets = UIEdgeInsetsMake(7, 0, -7, 0);

四 自定义tabBar

1 为了解决tabBar的问题,我们自定义tabBar(继承系统的UITabBar)

见图:

[img]http://img.blog.csdn.net/20160403221752214

2 修改tabBar内部子控件位置

3 把系统的tabBar替换为自己的tabBar(只需要创建一次)–(KVC)

具体实现代码:
#pragma mark - 运用自定义的tabBar
- (void)setUpTabBar
{
    //创建自定义tabBar
    XFJTabBar *tabBar = [[XFJTabBar alloc] init];
    //KVC赋值
    [self setValue:tabBar forKey:@"tabBar"];
}

4 重写layoutSubViews(布局tabBar中的子控件)

4.1 调整内部子控件的位置(遍历所有的子控件,然后判断子控件的类型,将中间的按钮位置空出来)

注意部分: 通过打印tabBar的子控件的类型,我们知道了按钮的类型是—> UITabBarButton这种类型的

代码详见:
#pragma mark - 布局子控件
- (void)layoutSubviews
{
    [super layoutSubviews];
    //获取子控件的总数
    NSInteger count = self.items.count + 1;
    //设置按钮的尺寸的属性
    CGFloat buttonX = 0;
    CGFloat buttonY = 0;
    CGFloat buttonW = self.XFJ_Width / count;
    CGFloat buttonH = self.XFJ_height;
    NSInteger i= 0;
    //遍历
    for (UIView *button in self.subviews) {
        //判断为该种类型的时候才进行下面
        if ([button isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            if (i == 2) {
                i = i + 1;
            }
            //按钮的X值
            buttonX = i * buttonW;
            //按钮的尺寸
            button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
            i ++;
        }
    }
    //设置发布按钮的饿摆放位置
    self.plusButton.center = CGPointMake(self.XFJ_Width * 0.5, self.XFJ_height * 0.5);
}
4.2 懒加载(通过懒加载创建发布按钮,然后在内部设置属性)—>由于只需要创建一次,所以用懒加载实现
#pragma mark - 懒加载
- (UIButton *)plusButton
{
    if (_plusButton == nil) {
        //创建按钮
        UIButton *plusButton = [UIButton buttonWithType:UIButtonTypeCustom];
        //设置按钮的图片(平常状态)
        [plusButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
        //高亮状态
        [plusButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
        //赋值
        self.plusButton = plusButton;
        //自适应
        [plusButton sizeToFit];

        [self addSubview:plusButton];
    }
    return _plusButton;
}

五 问题二

问题: 我们很多时候需要在外界直接修改控件的尺寸,但是传统的写法太麻烦.

解决办法:创建分类,在外界直接修改X,Y,width,Height的时候,能直接点出来

代码块一 :
@property CGFloat XFJ_x;
@property CGFloat XFJ_y;
@property CGFloat XFJ_Width;
@property CGFloat XFJ_height;
代码块二(在分类的内部实现了尺寸的修改,外面直接就可以点出来用):
- (void)setXFJ_x:(CGFloat)XFJ_x
{
    CGRect frame = self.frame;
    frame.origin.x = XFJ_x;
    self.frame = frame;
}

- (CGFloat)XFJ_x
{
    return self.frame.origin.x;
}

六 PCH文件

1 创建一个PCH文件(注意命名方式:和工程名一样),将全程序都需要的用到的文件都放到里面–>prefix

—-> PCH文件的实现思路:将pch文件中的代码,全部都拷贝一个到每个文件中,然后编译.

2 具体PCH配置:

详见图一:

[img]http://img.blog.csdn.net/20160403222528467
详见图二:(注意文件的路径)

[img]http://img.blog.csdn.net/20160403222612342

七 精华模块导航条的内容

1 导航条左边的按钮图片(封装一个分类)—->封装原因:我们想直接通过传入两张图,直接返回一个设置好的UIBarButtonItem对象.

—-> 写在分类中的代码:
+ (UIBarButtonItem *)itemWithImage:(UIImage *)image heightImage:(UIImage *)heighImage target:(id)target action:(SEL)action
{
    //创建按钮
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    //设置按钮图片
    [button setImage:image forState:UIControlStateNormal];
    //高亮状态
    [button setImage:heighImage forState:UIControlStateHighlighted];    
    //设置按钮的尺寸
    [button sizeToFit];
    //按钮的点击事件
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    //返回一个设置好的按钮
    return [[UIBarButtonItem alloc ]initWithCustomView:button];
}
—-> 设置左边图片:
- (void)setUpNavBar
{
    //左边的样式
    UIBarButtonItem *item = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"nav_item_game_icon"] heightImage:[UIImage imageNamed:@"nav_item_game_click_icon"] target:self action:@selector(game)];
—-> 设置右边的图片:
//右边的样式
    UIBarButtonItem *item1 = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"navigationButtonRandom"] heightImage:[UIImage imageNamed:@"navigationButtonRandomClick"] target:self action:@selector(task)];

    self.navigationItem.rightBarButtonItem = item1;
—-> 设置标题(注意:导航条的标题是一张图片)
#pragma mark - 设置导航条标题
- (void)setUpNavTitle
{
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MainTitle"]];
    self.navigationItem.titleView = imageView;
}

2 是不是所有的类都能拿到全局的外观?

解答: 不是,只有遵守了UIAppearance协议就可以通过appearance获取全局外观.

3 设置全局导航条的背景图片和显示的字体

具体代码:
//获取全局的导航条
    UINavigationBar *navBar = [UINavigationBar appearance];
    //设置背景图片
    [navBar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
    //设置字体
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:20];
    [navBar setTitleTextAttributes:dict];

八 bug

ios8会出现的bug:把短信界面导航条改了,联系人界面会出现黑的.

九 跳转设置

1 自定义设置控制器(UITableViewController)


[img]http://img.blog.csdn.net/20160403223307798

2 控制器”我”导航条右侧的图片

#pragma mark - 添加控制器我的右边的图片
- (void)setImageWithRight
{
    //控制器右边的图片
    UIBarButtonItem *item1 = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"mine-moon-icon"] heightImage:[UIImage imageNamed:@"mine-moon-icon-click"] target:self action:@selector(moon)];
    UIBarButtonItem *item2 = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"mine-setting-icon"] heightImage:[UIImage imageNamed:@"mine-setting-icon-click"] target:self action:@selector(setting)];
    //设置右边的图片
    self.navigationItem.rightBarButtonItems = @[item2,item1];  
}

3 跳转到设置界面

#pragma mark - 点击事件的实现(setting)
- (void)setting
{
    NSLog(@"setting");

    //创建跳转控制器
    XFJSettingViewController *setting = [[XFJSettingViewController alloc] init];

    //在push之前隐藏底部的tabBar
    setting.hidesBottomBarWhenPushed = YES;

    //跳转控制器
    [self.navigationController pushViewController:setting animated:YES];
}

4 跳转后出现的问题:

—-> 4.1 底部条没有隐藏
//在push之前隐藏底部的tabBar
    setting.hidesBottomBarWhenPushed = YES;
—-> 4.2 返回按钮样式(一定要在有内容的前提下,才能设置内边距)

5 设置全局返回按钮(重写push方法)

#pragma mark - 重写push方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog(@"%@",self.interactivePopGestureRecognizer);
    //判断,只有是分根控制器才能返回
    if (self.childViewControllers.count > 0) {
        //创建按钮
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        //设置按钮没有点击的图片
        [button setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
        //设置按钮点击后的图片
        [button setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
        //设置返回按钮字样
        [button setTitle:@"返回" forState:UIControlStateNormal];
        //设置返回按钮的标题的正常样式
        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        //设置返回按钮的标题的点击样式
        [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
        //设置按钮的尺寸
        [button sizeToFit];
        //设置按钮的监听方法
        [button addTarget:self action:@selector(backBtn) forControlEvents:UIControlEventTouchUpInside];
        //设置返回按钮与左边的距离
        button.contentEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
        //添加按钮
        viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    }
    [super pushViewController:viewController animated:animated];
}

十 重写push方法出现的bug—>系统的滑动返回功能失效了

1 解决办法: 清空代理—->会出现bug(假死状态:程序一直在跑,但是界面死了)
2 假死原因:在根控制器下,滑动返回,不应该在根控制器的view上滑动返回
3 解决办法:把自己设置为手势的代理,实现代理方法,判断,如果是根控制器,让手势没有效果(是否触发手势的代理方法)

代码块一:

self.interactivePopGestureRecognizer.delegate = self;

代码块二:

#pragma mark - 代理方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    //只有当导航控制器的子控制器的数量大于1的时候,才能侧滑
    return self.childViewControllers.count > 1;
}

十一 全屏滑动

1 分析:为什么导航控制器的滑动手势只能边缘滑动?

2 通过打印出代理的类型和action的方法,我们可以添加一个全屏滑动的功能,但是需要设置手势的代理,否则在根控制器的时候,又会出现假死的状态.

—->打印出系统侧滑功能的代理(红色部分是代理需要调用的方法)
<UIScreenEdgePanGestureRecognizer: 0x7fe5b2493980; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fe5b24920d0>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fe5b2493860>)>>
—-> 代码块一:
#pragma mark - 添加全屏侧滑功能
- (void)setWithScreenPan
{
    //创建手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
    //添加手势
    [self.view addGestureRecognizer:pan];

    //设置代理为自己
    pan.delegate = self;
}
代码块二:
//添加手势
    [self setWithScreenPan];

    //清空代理,但是必须是在添加手势之后
    self.interactivePopGestureRecognizer.enabled = NO;

十二 总结

1 该部分是有关tabBar和导航条的设置,里面涉及到自定义.设置好了系统的返回功能,但是由于重写而产生的一系列问题.里面已经涉及到了所有情况的解决思路,可能有一些不是很完整.后期我将一一解决.

2 今天只是框架二 ,明天我将为大家讲解后面的部分,大家有什么问题,麻烦留言,谢谢!!!!


......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-04 00:13:10  
移动开发 最新文章
深入了解android中的消息机制Handler
Android
Libgdx之BitmapFont字体
AndroidApp发布到应用市场的流程
Android开发找工作之前先看看这些知识点吧
View的事件分发机制解析
简单介绍了解白鹭引擎Egret
Cocos2d
android获取本地图片(二)
动画特效七:碰撞动画
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2017年9日历
2017-9-24 16:49:54
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --