百思不得姐框架(二)

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

框架二的效果图:

框架效果图

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

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

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

    return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2 问题:虽然抽取了分类,但是我们是不是想在用分类设置图片的时候,也能有插件提示功能呢?
设置插件功能图:(图一)

这里写图片描述

具体的设置思路:<—>见下图
2.1 按住option,点击桌面的左上角,找到前往,点击资源库
图一:

这里写图片描述

图二:

这里写图片描述

图三:

这里写图片描述

图四:

这里写图片描述

图五:

这里写图片描述

图六:

这里写图片描述

图七:

这里写图片描述

最后:找到插件的位置,具体做法就是先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];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
5 发布按钮显示不出来—>发布按钮的图片比较大,显示出来就会有问题
—-> 5.1 让正常状态下的图片也不被渲染(能达到效果)
nav2.tabBarItem.image = [UIImage originalWithImage:@"tabBar_publish_icon"];
 
 
  • 1
—-> 5.2 设置对应的控制器的tabBarItem,通过设置图片的内边距来实现(通过测试也不符合条件:原因是选中时候高亮,但是不选中的时候就会恢复状态)–>很明显是高亮状态
publish.tabBarItem.imageInsets = UIEdgeInsetsMake(7, 0, -7, 0);
 
 
  • 1

四 自定义tabBar

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

这里写图片描述

2 修改tabBar内部子控件位置
3 把系统的tabBar替换为自己的tabBar(只需要创建一次)–(KVC)
具体实现代码:
#pragma mark - 运用自定义的tabBar
- (void)setUpTabBar
{
    //创建自定义tabBar
    XFJTabBar *tabBar = [[XFJTabBar alloc] init];
    //KVC赋值
    [self setValue:tabBar forKey:@"tabBar"];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
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;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

五 问题二

问题: 我们很多时候需要在外界直接修改控件的尺寸,但是传统的写法太麻烦.
解决办法:创建分类,在外界直接修改X,Y,width,Height的时候,能直接点出来
代码块一 :
@property CGFloat XFJ_x;
@property CGFloat XFJ_y;
@property CGFloat XFJ_Width;
@property CGFloat XFJ_height;
 
 
  • 1
  • 2
  • 3
  • 4
代码块二(在分类的内部实现了尺寸的修改,外面直接就可以点出来用):
- (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;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

六 PCH文件

1 创建一个PCH文件(注意命名方式:和工程名一样),将全程序都需要的用到的文件都放到里面–>prefix
—-> PCH文件的实现思路:将pch文件中的代码,全部都拷贝一个到每个文件中,然后编译.
2 具体PCH配置:
详见图一:

这里写图片描述

详见图二:(注意文件的路径)

这里写图片描述

七 精华模块导航条的内容

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];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
—-> 设置左边图片:
- (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)];
 
 
  • 1
  • 2
  • 3
  • 4
—-> 设置右边的图片:
//右边的样式
    UIBarButtonItem *item1 = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"navigationButtonRandom"] heightImage:[UIImage imageNamed:@"navigationButtonRandomClick"] target:self action:@selector(task)];

    self.navigationItem.rightBarButtonItem = item1;
 
 
  • 1
  • 2
  • 3
  • 4
—-> 设置标题(注意:导航条的标题是一张图片)
#pragma mark - 设置导航条标题
- (void)setUpNavTitle
{
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MainTitle"]];
    self.navigationItem.titleView = imageView;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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];
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

八 bug

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

九 跳转设置

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

这里写图片描述

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];  
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
3 跳转到设置界面
#pragma mark - 点击事件的实现(setting)
- (void)setting
{
    NSLog(@"setting");

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

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

    //跳转控制器
    [self.navigationController pushViewController:setting animated:YES];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
4 跳转后出现的问题:
—-> 4.1 底部条没有隐藏
//在push之前隐藏底部的tabBar
    setting.hidesBottomBarWhenPushed = YES;
 
 
  • 1
  • 2
—-> 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];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

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

1 解决办法: 清空代理—->会出现bug(假死状态:程序一直在跑,但是界面死了)
2 假死原因:在根控制器下,滑动返回,不应该在根控制器的view上滑动返回
3 解决办法:把自己设置为手势的代理,实现代理方法,判断,如果是根控制器,让手势没有效果(是否触发手势的代理方法)
代码块一:
self.interactivePopGestureRecognizer.delegate = self;
 
 
  • 1
代码块二:
#pragma mark - 代理方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    //只有当导航控制器的子控制器的数量大于1的时候,才能侧滑
    return self.childViewControllers.count > 1;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

十一 全屏滑动

1 分析:为什么导航控制器的滑动手势只能边缘滑动?
2 通过打印出代理的类型和action的方法,我们可以添加一个全屏滑动的功能,但是需要设置手势的代理,否则在根控制器的时候,又会出现假死的状态.
—->打印出系统侧滑功能的代理(红色部分是代理需要调用的方法)
<UIScreenEdgePanGestureRecognizer: 0x7fe5b2493980; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fe5b24920d0>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fe5b2493860>)>>
 
 
  • 1
—-> 代码块一:
#pragma mark - 添加全屏侧滑功能
- (void)setWithScreenPan
{
    //创建手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
    //添加手势
    [self.view addGestureRecognizer:pan];

    //设置代理为自己
    pan.delegate = self;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
代码块二:
//添加手势
    [self setWithScreenPan];

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

十二 总结

1 该部分是有关tabBar和导航条的设置,里面涉及到自定义.设置好了系统的返回功能,但是由于重写而产生的一系列问题.里面已经涉及到了所有情况的解决思路,可能有一些不是很完整.后期我将一一解决.
2 今天只是框架二 ,明天我将为大家讲解后面的部分,大家有什么问题,麻烦留言,谢谢!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值