用标签页TitleSwitch切换不通的控制器

教程效果:

项目开发中效果:

各种源码:

TitleSwitch.h 与 TitleSwitch.m (这个是修改过的升级版本)

//
//  TitleSwitch.h
//  TitleSwitch
//
//  Created by YouXianMing on 14/11/4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 * 使用细节
 *

 TitleSwitch *titleSwitch              = [[TitleSwitch alloc] initWithFrame:CGRectMake(0, 100, 320, 40)];
 titleSwitch.titles                    = @[@"YouXianMing", @"NoZuoNoDie", @"BlueShit"];
 titleSwitch.titleFont                 = [UIFont systemFontOfSize:15.f];
 titleSwitch.lineWidth                 = 1.f;
 titleSwitch.canTouchOnlyButtonOneTime = YES;
 titleSwitch.delegate                  = self;
 [titleSwitch createTitleSwitchView];

 [self.view addSubview:titleSwitch];

 *
 *
 */

@protocol TitleSwitchDelegate <NSObject>
@optional
- (void)willSelectIndex:(NSInteger)index;
- (void)didSelectIndex:(NSInteger)index;
@end

@interface TitleSwitch : UIView

/**
 *  协议
 */
@property (nonatomic, assign) id<TitleSwitchDelegate> delegate;

/**
 *  作为按钮的标题
 */
@property (nonatomic, strong) NSArray  *titles;

/**
 *  线的宽度
 */
@property (nonatomic, assign) CGFloat   lineWidth;

/**
 *  线的颜色
 */
@property (nonatomic, strong) UIColor  *lineColor;

/**
 *  标题字体
 */
@property (nonatomic, strong) UIFont   *titleFont;

/**
 *  普通标题颜色
 */
@property (nonatomic, strong) UIColor  *normalTitleColor;

/**
 *  选中标题的颜色
 */
@property (nonatomic, strong) UIColor  *selectedTitleColor;

/**
 *  一次只能按一个按钮触发动画效果
 */
@property (nonatomic, assign) BOOL      canTouchOnlyButtonOneTime;

/**
 *  开启按钮点击时高亮颜色的效果 & 高亮颜色
 */
@property (nonatomic, assign) BOOL      enableButtonTitleHighlighted;
@property (nonatomic, strong) UIColor  *highlightedTitleColor;

/**
 *  小横线条的X方向的位移值(可以设置动画)
 */
@property (nonatomic, assign) CGFloat   linePositionX;
/**
 *  根据linePositionX重设标题颜色
 */
- (void)resetTilte;

/**
 *  创建TitleSwitch的view出来
 */
- (void)createTitleSwitchView;

@end
//
//  TitleSwitch.m
//  TitleSwitch
//
//  Created by YouXianMing on 14/11/4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "TitleSwitch.h"

typedef enum : NSUInteger {
    NORMAL_BUTTON = 0x11,
    LINE_VIEW     = 0x1122,
} ENUM_VIEWTAG;

@implementation TitleSwitch

- (void)createTitleSwitchView {

    // 如果没有title,则直接返回
    if (_titles.count == 0) {
        return;
    }

    // 获取尺寸
    CGFloat frameWidth  = self.bounds.size.width;
    CGFloat frameHeight = self.bounds.size.height;

    // 计算按钮的宽度&高度
    CGFloat buttonWidth      = frameWidth / _titles.count;
    CGFloat buttonHeight     = 0;
    CGFloat defaultLineWidth = 2.f;
    if (_lineWidth == 0) {
        buttonHeight = frameHeight - defaultLineWidth; // 默认线条占用一个像素
    } else {
        buttonHeight = frameHeight - _lineWidth;
    }

    // 初始化所有按钮
    for (int i = 0; i < _titles.count; i++) {
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(buttonWidth * i,
                                                                      0,
                                                                      buttonWidth,
                                                                      buttonHeight)];
        button.tag       = NORMAL_BUTTON + i;
        [self addSubview:button];

        [button setTitle:_titles[i] forState:UIControlStateNormal];

        // 普通颜色
        if (i == 0) {
            [self selectButtonStyle:button];
        } else {
            [self normalButtonStyle:button];
        }

        // 高亮颜色
        if (_enableButtonTitleHighlighted == YES && _highlightedTitleColor) {
            [button setTitleColor:_highlightedTitleColor forState:UIControlStateHighlighted];
        }

        // 添加事件
        [button addTarget:self action:@selector(buttonsEvent:) forControlEvents:UIControlEventTouchUpInside];

        // 设置字体
        if (_titleFont) {
            button.titleLabel.font = _titleFont;
        }
    }

    // 初始化横线view
    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, buttonHeight + 1, buttonWidth,
                                                                (_lineWidth == 0 ? defaultLineWidth : _lineWidth))];
    lineView.tag     = LINE_VIEW;
    [self addSubview:lineView];
    if (_lineColor) {
        lineView.backgroundColor = _lineColor;
    } else {
        lineView.backgroundColor = [UIColor redColor];
    }
}

/**
 *  按钮事件
 *
 *  @param button 触摸事件中的按钮
 */
- (void)buttonsEvent:(UIButton *)button {
    // 获取到lineView
    UIView *lineView      = [self viewWithTag:LINE_VIEW];

    // 哪一个button
    NSInteger whichButton = button.tag - NORMAL_BUTTON;

    // 计算按钮的宽度&高度
    CGFloat frameWidth    = self.bounds.size.width;
    CGFloat buttonWidth   = frameWidth / _titles.count;

    [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIButton *tmp = (UIButton *)obj;
        if ([tmp isKindOfClass:[UIButton class]]) {
            if (tmp == button) {
                [self selectButtonStyle:tmp];
            } else {
                [self normalButtonStyle:tmp];
            }
        }
    }];

    // 做动画
    if (_canTouchOnlyButtonOneTime == YES) {
        self.userInteractionEnabled = NO;
    }

    if (_delegate && [_delegate respondsToSelector:@selector(willSelectIndex:)]) {
        [_delegate willSelectIndex:whichButton];
    }

    [UIView animateWithDuration:0.25f animations:^{
        CGRect rect    = lineView.frame;
        rect.origin.x  = whichButton * buttonWidth;
        lineView.frame = rect;
    } completion:^(BOOL finished) {
        if (_canTouchOnlyButtonOneTime == YES) {
            self.userInteractionEnabled = YES;
        }

        if (_delegate && [_delegate respondsToSelector:@selector(didSelectIndex:)]) {
            [_delegate didSelectIndex:whichButton];
        }
    }];
}

/**
 *  选中按钮的样式
 *
 *  @param button 按钮
 */
- (void)selectButtonStyle:(UIButton *)button {

    if (_selectedTitleColor) {
        [button setTitleColor:_selectedTitleColor
                     forState:UIControlStateNormal];
    } else {
        [button setTitleColor:[UIColor redColor]
                     forState:UIControlStateNormal];
    }
}

/**
 *  普通按钮样式
 *
 *  @param button 按钮
 */
- (void)normalButtonStyle:(UIButton *)button {

    if (_normalTitleColor) {
        [button setTitleColor:_normalTitleColor
                     forState:UIControlStateNormal];
    } else {
        [button setTitleColor:[UIColor colorWithRed:0.369 green:0.369 blue:0.369 alpha:1]
                     forState:UIControlStateNormal];
    }
}

- (void)resetTilte {

    // 获取尺寸
    CGFloat frameWidth  = self.bounds.size.width;

    // 计算按钮的宽度&高度
    CGFloat buttonWidth      = frameWidth / _titles.count;

    // 获取到位置
    NSInteger index = _linePositionX / buttonWidth + 1;

    [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        UIButton *tmp = (UIButton *)obj;
        if ([tmp isKindOfClass:[UIButton class]]) {
            if (idx == index) {
                [self selectButtonStyle:tmp];
            } else {
                [self normalButtonStyle:tmp];
            }
        }
    }];
}

#pragma mark - 重写各种setter,getter方法
@synthesize linePositionX = _linePositionX;
- (void)setLinePositionX:(CGFloat)linePositionX {
    _linePositionX = linePositionX;

    // 获取到lineView
    UIView *lineView   = [self viewWithTag:LINE_VIEW];
    if (lineView) {
        CGRect rect    = lineView.frame;
        rect.origin.x  = linePositionX;
        lineView.frame = rect;
    }
}
- (CGFloat)linePositionX {
    return _linePositionX;
}

@end

WxHxD.h 与 WxHxD.m

//
//  WxHxD.h
//  PM2.5
//
//  Created by YouXianMing on 14/10/29.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface WxHxD : NSObject

/**
 *  应用程序中可以放置view的区间的高度(部分区域会被导航栏控制器的高度占有而不计算在类)
 *
 *  @return 高度
 */
+ (CGFloat)appHeight;

/**
 *  屏幕高度
 *
 *  @return 屏幕高度
 */
+ (CGFloat)screenHeight;

/**
 *  屏幕宽度
 *
 *  @return 屏幕宽度
 */
+ (CGFloat)screenWidth;

/**
 *  状态栏高度
 *
 *  @return 状态栏高度
 */
+ (CGFloat)statusBarHeight;

/**
 *  导航栏控制器的高度
 *
 *  @return 导航栏控制器的高度
 */
+ (CGFloat)navigationBarHeight;

/**
 *  标签栏控制器的高度
 *
 *  @return 标签栏控制器的高度
 */
+ (CGFloat)tabbarHeight;

/**
 *  状态栏与导航栏控制器一起的高度
 *
 *  @return 状态栏与导航栏控制器一起的高度
 */
+ (CGFloat)statusBarAndNavigationBarHeight;

@end
//
//  WxHxD.m
//  PM2.5
//
//  Created by YouXianMing on 14/10/29.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "WxHxD.h"

@implementation WxHxD

+ (CGFloat)appHeight {
    return [UIScreen mainScreen].applicationFrame.size.height;
}

+ (CGFloat)screenHeight {
    return [UIScreen mainScreen].bounds.size.height;
}

+ (CGFloat)screenWidth {
    return [UIScreen mainScreen].bounds.size.width;
}

+ (CGFloat)statusBarHeight {
    return 20.f;
}

+ (CGFloat)navigationBarHeight {
    return 44.f;
}

+ (CGFloat)tabbarHeight {
    return 49.f;
}

+ (CGFloat)statusBarAndNavigationBarHeight {
    return (20.f + 44.f);
}

@end

控制器源码:

//
//  FirstController.m
//  SwitchController
//
//  Created by YouXianMing on 14/11/5.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "FirstController.h"

@interface FirstController ()

@end

@implementation FirstController

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label      = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
    label.center        = self.view.center;
    label.text          = @"FirstController";
    label.font          = [UIFont fontWithName:@"HelveticaNeue-Thin" size:35.f];
    label.textAlignment = NSTextAlignmentCenter;

    [self.view addSubview:label];
}

@end
//
//  SecondController.m
//  SwitchController
//
//  Created by YouXianMing on 14/11/5.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "SecondController.h"

@interface SecondController ()

@end

@implementation SecondController

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label      = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
    label.center        = self.view.center;
    label.text          = @"SecondController";
    label.font          = [UIFont fontWithName:@"HelveticaNeue-Thin" size:35.f];
    label.textAlignment = NSTextAlignmentCenter;

    [self.view addSubview:label];
}

@end

主控制器源码:

//
//  ViewController.m
//  SwitchController
//
//  Created by YouXianMing on 14/11/5.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "TitleSwitch.h"
#import "WxHxD.h"

#import "FirstController.h"
#import "SecondController.h"

@interface ViewController ()<TitleSwitchDelegate, UIScrollViewDelegate>

{
    TitleSwitch  *titleSwitch;
}

@property (nonatomic, strong) UIScrollView *mainScrollView; // 滑动用的ScrollView

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 隐藏状态栏(需要先设置plist文件)
    [UIApplication sharedApplication].statusBarHidden = YES; // 关闭状态栏

    // 初始化UIScrollView
    [self initScrollView];

    // 初始化标签控制器
    [self initTitleSwitch];

    // 初始化两个控制器
    FirstController *first  = [FirstController new];
    [self addChildViewController:first];  // 将控制器first变为当前控制器的子控制器
    CGRect firstRect        = first.view.frame;
    firstRect.origin.x      = [WxHxD screenWidth] * 0; // view值偏移量为 0*screenWidth
    first.view.frame        = firstRect;

    SecondController *second = [SecondController new];
    [self addChildViewController:second]; // 将控制器second变为当前控制器的子控制器
    CGRect secondRect        = second.view.frame;
    secondRect.origin.x      = [WxHxD screenWidth] * 1; // view值偏移量为 1*screenWidth
    second.view.frame        = secondRect;

    // 加载控制器的view
    [_mainScrollView addSubview:first.view];
    [_mainScrollView addSubview:second.view];
}

/**
 *  初始化UIScrollView
 */
- (void)initScrollView {
    // 当前显示艺术品的控制器
    _mainScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    _mainScrollView.contentSize   = CGSizeMake([WxHxD screenWidth] * 2, [WxHxD screenHeight]);
    _mainScrollView.pagingEnabled = YES;
    _mainScrollView.delegate      = self;
    _mainScrollView.bounces       = NO;
    _mainScrollView.showsHorizontalScrollIndicator = NO;
    [self.view addSubview:_mainScrollView];
}

#pragma mark - UIScrollView的代理
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    titleSwitch.linePositionX = scrollView.contentOffset.x / 2.f;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [titleSwitch resetTilte];
}

/**
 *  初始化标签控制器
 */
- (void)initTitleSwitch {
    // 标题切换用
    titleSwitch              = [[TitleSwitch alloc] initWithFrame:CGRectMake(0, 0, [WxHxD screenWidth], 40)];
    titleSwitch.tag          = 0x112244;

    // 添加灰色的线条
    UIView *grayLine = [[UIView alloc] initWithFrame:CGRectMake(0, 40, [WxHxD screenWidth], 1)];
    grayLine.backgroundColor = [UIColor colorWithRed:0.827 green:0.827 blue:0.827 alpha:1];
    [titleSwitch addSubview:grayLine];

    titleSwitch.backgroundColor           = [UIColor colorWithRed:0.949 green:0.949 blue:0.949 alpha:1];
    titleSwitch.selectedTitleColor        = [UIColor colorWithRed:0.843 green:0.000 blue:0.000 alpha:1];
    titleSwitch.titles                    = @[@"YouXianMing",
                                              @"NoZuoNoDie"];
    titleSwitch.lineWidth                 = 1.f;
    titleSwitch.titleFont                 = [UIFont systemFontOfSize:15.f];
    titleSwitch.canTouchOnlyButtonOneTime = YES;
    titleSwitch.delegate                  = self;
    [titleSwitch createTitleSwitchView];
    [self.view addSubview:titleSwitch];
}

#pragma mark - TitleSwitch的代理
- (void)willSelectIndex:(NSInteger)index {
    if (index == 0) {

        CGPoint point = _mainScrollView.contentOffset;
        point.x       = 0;
        [UIView animateWithDuration:0.25f animations:^{
            _mainScrollView.contentOffset = point;
        }];

        [self bringTitleToFrount];

    } else {
        CGPoint point = _mainScrollView.contentOffset;
        point.x       = [WxHxD screenWidth];
        [UIView animateWithDuration:0.25f animations:^{
            _mainScrollView.contentOffset = point;
        }];

        [self bringTitleToFrount];
    }
}

/**
 *  将标题提到最前面
 */
- (void)bringTitleToFrount {
    UIView *tmpView = [self.view viewWithTag:0x112244];
    [self.view bringSubviewToFront:tmpView];
}

@end

解析:

时间: 2024-10-29 04:56:19

用标签页TitleSwitch切换不通的控制器的相关文章

bootstrap 标签页tab切换js(含报错原因)

booststrap 标签页的tab切换,相信大家已经都很熟悉了,在boot官网示例以及其他网站已经很多罗列相关代码的了,这里就不赘述了.这里主要贴下让boot标签页默认显示哪个标签页的js. 主要留作自己工作备忘. 1 $('a[data-toggle="tab"]') 2 $('#myTab a[href="#profile"]').tab('show') 3 $('#myTab a:first').tab('show') 4 $('#myTab a:last'

在jsp中同一页面中多个标签页之间切换数据展示

示例图片: 像这样的上面多个tab页下面也有多个tab页面,其实只要学会一个嵌套就可以了,现在就说一下简单的一个页面的多个tab页面的展示

Bootstrap入门(二十七)JS插件4:标签页

标签页的切换可以带动内容的变化 首先我们引入CSS文件 <link href="bootstrap.min.css" rel="stylesheet"> 在里面创建一个容器div,添加<ul><li>来承载标签,下拉菜单也是可以嵌套进去的 第一个默认设置为被选中 <ul id="mytab" class="nav nav-tabs"> <li class="act

python selenium-webdriver 标签页切换(十四)

测试过程中有时候会遇到点击某个按钮或者链接会弹出新的窗口,这时候我们的操作的页面还保持着最初打开页面,但是此时我们需要操作新打开的页面上的功能,这个时候我们需要切换一下标签页 . 其实页面的切换与frame的切换比较相识,一种切换时本页面内frame的操作,而标签页面是多页面的操作,道理很相似.下面讲解下操作页面标签会涉及到那些方法. driver.current_window_handle                      #获取当前窗口的句柄 driver.window_handle

标签页(tab)切换的原生js,jquery和bootstrap实现

概述 这是我在学习课程Tab选项卡切换效果时做的总结和练手. 原课程中只有原生js实现,jquery和bootstrap实现是我自己补上的. 本节内容 标签页(tab)切换的原生js实现 标签页(tab)切换的jquery实现 标签页(tab)切换的bootstrap实现 标签页(tab)切换的原生js实现 说明: 代码是我自己写的,与课程中的不一样. 主要利用display:none来把部分内容隐藏而显示其它内容. 遇到了事件的循环绑定,我是利用添加id使其成为钩子来解决的. 代码: <!DO

解决Bootstrap 标签页(Tab)插件切换echarts不显示问题

1.参考连接:https://blog.csdn.net/qq_24313955/article/details/78363981 问题描述:在echarts跟bootstrap选项卡整合的时候,默认第一个选中选项卡可以正常加载echarts图表,但是切换其他选项的时候不能渲染出其他选项卡echarts图表.(这里暂时未考虑自适应问题). 由于使用的格式和参考不一样,所以自己贴一下,方便自己以后使用. 2.在js文件页面最上面定义一个js数组.如var charts = new Array();

selenium 对浏览器标签页进行关闭和切换

关闭标签页 # 1.关闭浏览器全部标签页 driver.quit() # 2.关闭当前标签页(从标签页A打开新的标签页B,关闭标签页A) driver.close() 切换标签页 from selenium import webdriver browser=webdriver.Firefox() browser.get('xxxxx') # 获取当前窗口句柄(窗口A) handle = browser.current_window_handle # 打开一个新的窗口 browser.find_e

web前端中实现多标签页切换的效果

在这里,实现多标签页效果的方法有两个,一个是基于DOM的,另一个是基于jquery的,此次我写的是一个对于一个电话套餐的不同,显示不同的标签页 方法一: 首先,我们要把页面的大体框架和样式写出来,html和css代码如下: <ul id="tab">    <li id="tab1" onclick="show(1)">10元套餐</li>    <li id="tab2" oncli

vue单页面条件下添加类似浏览器的标签页切换功能

在用vue开发的时候,单页面应用程序,而又有标签页这种需求,各种方式实现不了, 从这个 到这个,然后再返回上面那个 因为每个标签页的route不一样,导致组件重新渲染的问题,怎么都不知道如何实现......... 简直郁闷到爆炸,后来和同学谈起的时候,说起生命周期这个才恍然大悟, 对于vue的生命周期,因为用的少,本身多用的是created,mounted这两个,都忘记beforeDestroy这些了,然后抓瞎了好久 实现方式是 每次销毁组件之前   缓存数据    能够用到的是 this.$d