• 控制器切换(网易新闻效果)


    有的时候设计开发的app用了UITabBarController控制器后,跳转到相应的导航栏控制器,而导航栏的控制器又有子控制,再子控制器中实现控制器的切换一般都不再采用UITabBarController实现,而是自己设计相应的控制器切换按钮实现,类似于网易新闻那样的效果.
    如网易新闻下边的导航条
    最终实现的效果如下,点击按钮 切换 控制器:
    效果图
    具体实现原理:
    在AppDelegate的函数中设置主窗口:

    -  (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {   //初始化窗口
        self.window = [[UIWindow alloc] init];
        self.window.frame = [UIScreen mainScreen].bounds;
        //设置主控制器
        XCMainController *mainVc = [[XCMainController alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:mainVc];
        self.window.rootViewController = nav;
        //显示
        [self.window makeKeyAndVisible];
        return YES;
    }
    思想:创建一个主控制,然后用主控制来管理各个子控制,同时自定义一个导航按钮切换View,在其中添加各个按钮,并实现代理方法,当点击了按钮后,可以在主控制实现其代理方法,然后就可以完成相应的控制器切换.
    初始化主控制器:
    
    #import "XCNavBar.h"
    - (void)viewDidLoad{
        [super viewDidLoad];
        //设置导航栏题目
        self.navigationItem.title = @"主控制器";
        //添加导航条
        XCNavBar *navBar = [[XCNavBar alloc] init];
        navBar.backgroundColor = [UIColor whiteColor];
        navBar.delegate = self;
        navBar.frame = CGRectMake(0, navigationH, viewW, navBarH);
        [self.view addSubview:navBar];
     }

    自定义导航按钮:

    .h文件
    typedef enum{//按钮类型
        XCNavBarButtonTypeOne = 0,
        XCNavBarButtonTypeTwo,
        XCNavBarButtonTypeThree,
        XCNavBarButtonTypeFour
    } XCNavBarButtonType;
    //代理实现
    @class XCNavBar;
    @protocol XCNavBarDelegate <NSObject>
    @optional//可选的
    - (void)navBar:(XCNavBar *)navBar didSelectedButton:(XCNavBarButtonType)buttonType;
    @end
    //属性方法
    @property (nonatomic, weak) id<XCNavBarDelegate> delegate;
    
    .m文件
    //属性
    @property (nonatomic, strong) UIButton *selectedBtn;
    //具体方法
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
        //添加按钮
            [self addButtonWithTitle:@"one" buttonType:XCNavBarButtonTypeOne];
            [self addButtonWithTitle:@"two" buttonType:XCNavBarButtonTypeTwo];
            [self addButtonWithTitle:@"three" buttonType:XCNavBarButtonTypeThree];
            [self addButtonWithTitle:@"four" buttonType:XCNavBarButtonTypeFour];
        }
        return self;
    }
    
    //添加一个按钮
    - (void)addButtonWithTitle:(NSString *)title buttonType:(XCNavBarButtonType)type{
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitle:title forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
    
        [btn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateDisabled];
    
        btn.tag = type;
        [self addSubview:btn];
        [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
        if (type == XCNavBarButtonTypeOne){
            [self btnClick:btn];
        }
    }
    //监听按钮点击
    - (void)btnClick:(UIButton *)btn{
        self.selectedBtn.enabled = YES;
        btn.enabled = NO;
        self.selectedBtn = btn;
        //实现代理方法
        if ([self.delegate respondsToSelector:@selector(navBar:didSelectedButton:)]) {
            [self.delegate navBar:self didSelectedButton:btn.tag];
        }    
    }
    //计算子控件的位置
    - (void)layoutSubviews{
        [super layoutSubviews];
        NSInteger count = self.subviews.count;
        CGFloat btnW = self.bounds.size.width / count;
        CGFloat btnH = self.bounds.size.height;
        CGFloat btnX = 0;
        CGFloat btnY = 0;
        for (int i = 0; i < count; i++) {
            UIButton *btn = self.subviews[i];
            btnX = i * btnW;
            btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
        }
    }

    主控制器中添加自控制器,并实现控制器的相应切换

    /** 屏幕宽度 */
    #define viewW self.view.frame.size.width
    /** 屏幕高度 */
    #define viewH self.view.frame.size.height
    /** 子控制器高度 */
    #define subViewH (viewH - navigationH - navBarH)
    /** 导航条高度 */
    #define navigationH 64
    /** 导航按钮高度 */
    #define navBarH 44
    /** 子控制器Y值 */
    #define subViewY (navigationH + navBarH)
    //属性
    //强引用,否则会被释放
    @property (nonatomic, strong) XCOneController *oneVc;
    @property (nonatomic, strong) XCTwoViewController *twoVc;
    @property (nonatomic, strong) XCThreeController *threeVc;
    @property (nonatomic, strong) XCFourController *fourVc;
    /** 当前控制器 */
    @property (nonatomic, strong) UIViewController *currentView;
    //具体方法
    - (void)viewDidLoad{
        [super viewDidLoad];
       //添加自控制器
        self.oneVc = [[XCOneController alloc] init];
        self.oneVc.view.frame = CGRectMake(0, subViewY, viewW, subViewH);
        [self addChildViewController:self.oneVc];
    
        self.twoVc = [[XCTwoViewController alloc] init];
        self.twoVc.view.frame = CGRectMake(0, subViewY, viewW, subViewH);
        [self addChildViewController:self.twoVc];
    
        self.threeVc = [[XCThreeController alloc] init];
        self.threeVc.view.frame = CGRectMake(0, subViewY, viewW, subViewH);
        [self addChildViewController:self.threeVc];
    
        self.fourVc = [[XCFourController alloc] init];
        self.fourVc.view.frame = CGRectMake(0, subViewY, viewW, subViewH);
        [self addChildViewController:self.fourVc];
    
        //设置默认控制器
        self.currentView = self.oneVc;
        [self.view addSubview:self.oneVc.view];
    }
    /**
     *  控制器切换方法实现
     */
    - (void)replaceOldViewController:(UIViewController *)oldVc toNewViewController:(UIViewController *)newVc{
        //要切换的控制器为当前控制器,则直接返回
        if (self.currentView == newVc) return;
        /**
         *  transitionFromViewController:toViewController:duration:options:animations:completion:
         *  fromViewController    当前显示在父视图控制器中的子视图控制器
         *  toViewController        将要显示的姿势图控制器
         *  duration                动画时间(这个属性,old friend 了 O(∩_∩)O)
         *  options              动画效果(渐变,从下往上等等,具体查看API)UIViewAnimationOptionTransitionCrossDissolve
         *  animations            转换过程中得动画
         *  completion            转换完成
         */
        [self addChildViewController:newVc];
        [self transitionFromViewController:oldVc toViewController:newVc duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:^(BOOL finished) {
            if (finished) {
                [newVc didMoveToParentViewController:self];
                [oldVc willMoveToParentViewController:nil];
                [oldVc removeFromParentViewController];
                self.currentView = newVc;
            }else{
                self.currentView = oldVc;
            }
        }];
    }
    

    最后在主控制器中导航按钮的实现代理方法,完成控制器的切换

    #pragma mark - XCNavBarDelegate代理方法
    - (void)navBar:(XCNavBar *)navBar didSelectedButton:(XCNavBarButtonType)buttonType{
        switch (buttonType) {
            case XCNavBarButtonTypeOne:
                [self replaceOldViewController:self.currentView toNewViewController:self.oneVc];
                break;
            case XCNavBarButtonTypeTwo:
                [self replaceOldViewController:self.currentView toNewViewController:self.twoVc];
                break;
            case XCNavBarButtonTypeThree:
                [self replaceOldViewController:self.currentView toNewViewController:self.threeVc];
                break;
            case XCNavBarButtonTypeFour:
                [self replaceOldViewController:self.currentView toNewViewController:self.fourVc];
                break;
            default:
                break;
        }
    }

    最后:源代码地址
    github源码地址

    不积跬步,无以至千里;不积小流,无以成江海。
  • 相关阅读:
    seaborn基础整理
    matplotlib基础整理
    pandas基础整理
    numpy基础整理
    二分算法的应用——不只是查找值!
    二分算法的应用——Codevs 1766 装果子
    数据挖掘实战(二)—— 类不平衡问题_信用卡欺诈检测
    数论:素数判定
    MySQL学习(二)——MySQL多表
    MySQL学习(一)——Java连接MySql数据库
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779812.html
Copyright © 2020-2023  润新知