iOS开发不借助第三方控件实现侧边栏效果

简介:

最近在研究iOS程序的侧边栏,因为发现渐渐的iOS的程序也开始走侧边栏的风格了,QQ,今日头条,Path(Path算最早出现侧边栏的app了,所以也把侧边栏效果说成是Path效果),所以就研究了下。

然后发现Git Hub上有很多侧边栏的控件,这些控件效果也都挺玄的,但是我想找到不用第三方控件自己实现侧边栏呢?后来参照这篇blog,然后自己搞了下,算搞清楚了。下面详细介绍一下吧。

1. 

首先我们需要在storyboard里面新建3个view controlle,这里也可以是navigation controller,但是我还是习惯直接用view controller就可以了,跳转都自己来实现。

2. 

接下来需要新建3个类,

ContainerViewController是一个容器类的VC,作用是放置MainVC和SideVC,就好比TabbarViewController一样,它只是一个容器,真正调整页面的是在其他VC中。

3. 

先不用管这3个ViewController如何实现,我们转到storyboard中,分别把设置3个ViewController的identifier,像这个样子


ContainerViewController可以不设置storyboard,但是mainVC和sideVC一定要设置好storyboard ID,然后你还可以自己编辑一下Main VC和sideVC,这样可以更清晰地看到侧边栏的效果。

最终的StoryBoard是这样的:

最上面是ContainerViewController,接下来从右到左分别是MainViewController和SideViewController。


4. 

好了,接下来我们就开始coding把。我这里想要做的效果是滑屏或者点击mainVC左上角的按钮都可以打开侧边栏,然后当侧边栏显示的时候,滑屏或者点击右侧的mainVC,都能隐藏侧边栏。

我们一步一步来分析代码吧:

其实主要是ContainerViewController

ContainerViewController.h

//  这个相当于是容器的VC,里面存放主界面和侧边栏

#import <UIKit/UIKit.h>
#import "MainViewController.h"
#import "SideViewController.h"

@interface ContainerViewController : UIViewController<UIGestureRecognizerDelegate>{}

@property(nonatomic, strong) MainViewController *centerController;
@property(nonatomic, strong) SideViewController *leftController;

- (void)showSideView;
- (void)hideSideView;

@end


我们import了mainVC和sideVC,然后定义了两个property和两个method


ContainerViewController.m

//

#import "ContainerViewController.h"

@interface ContainerViewController ()

@end

@implementation ContainerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    
    _centerController = (MainViewController *)[storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
    _centerController.fatherViewController = self;
    
    _leftController = (SideViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"];
    
    [self.view addSubview:_centerController.view];
    [_centerController.view setTag:1];
    [_centerController.view setFrame:self.view.bounds];
    
    [self.view addSubview:_leftController.view];
    [_leftController.view setTag:2];
    [_leftController.view setFrame:self.view.bounds];
    
    [self.view bringSubviewToFront:_centerController.view];
    
    //add swipe gesture
    UISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
    [swipeGestureRight setDirection:UISwipeGestureRecognizerDirectionRight];
    [_centerController.view addGestureRecognizer:swipeGestureRight];
    
    UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
    [swipeGestureLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
    [_centerController.view addGestureRecognizer:swipeGestureLeft];
}

-(void) swipeGesture:(UISwipeGestureRecognizer *)swipeGestureRecognizer {
    
    CALayer *layer = [_centerController.view layer];
    layer.shadowColor = [UIColor blackColor].CGColor;
    layer.shadowOffset = CGSizeMake(1, 1);
    layer.shadowOpacity = 1;
    layer.shadowRadius = 20.0;
    if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionRight) {
        [self showSideView];
    }
    if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
        [self hideSideView];
    }
}

// 显示侧边栏,单独写成一个函数,供mainVC点击头像时调用
- (void)showSideView{
    [_leftController.view setHidden:NO];
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    if (_centerController.view.frame.origin.x == self.view.frame.origin.x || _centerController.view.frame.origin.x == -200) {
        [_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x+200, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];
    }
    
    [UIView commitAnimations];
}

- (void)hideSideView{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    if ( _centerController.view.frame.origin.x == 200) {
        [_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x-200, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];
    }
    [UIView commitAnimations];
    // 最后调用防止出现白底
    [_leftController.view setHidden:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

在viewDidload方法里面,我们从storyboard中获取到两个ViewController,注意我的sideviewcontroller起的名字是LeftViewController,也就是在storyboard ID里面要写成这个名字。

然后添加进去了滑屏手势,分别是向左滑和向右滑

接下里在滑屏的代理里面定义了滑屏的动作。这里为什么要把显示/隐藏sideview单独做成两个method呢?因为一会我们要实现在mainVC里面点击头像的时候能够调用ContainerVC里的这两个函数!

接下来看看MainVC如何实现吧

MainViewController.h

#import <UIKit/UIKit.h>

@class ContainerViewController;

@interface MainViewController : UIViewController

- (IBAction)showSideView:(id)sender;
@property (nonatomic, strong) ContainerViewController* fatherViewController;

@end


注意这里用@class来引入ContainerVC,不在头文件里面#import是为了防止循环引用。

然后我们定义一个property,fatherViewController,它是一个ContainerViewController的实例。

showSideView的IBAction是头像那个button的点击动作。


MainViewController.m

#import "MainViewController.h"
#import "ContainerViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (IBAction)showSideView:(id)sender {
    [self.fatherViewController showSideView];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self.fatherViewController hideSideView];
}
@end

这样在mainViewController的点击头像button的动作就能调用fatherViewController,也就是ContainerViewController里面的showSideView动作了。

touchesBegan是当点击mainViewController的时候,隐藏侧边栏的。

以为SideViewController都是在storyboard里面拖入控件完成的,所以不需要写什么代码。

当然,这里仅仅是左侧的侧边栏,想要看两侧的侧边栏方法,查阅这里



目录
相关文章
|
1月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
85 3
|
6天前
|
API 定位技术 iOS开发
IOS开发基础知识:什么是 Cocoa Touch?它在 iOS 开发中的作用是什么?
【4月更文挑战第18天】**Cocoa Touch** 是iOS和Mac OS X应用的核心框架,包含面向对象库、运行时系统和触摸优化工具。它提供Mac验证的开发模式,强调触控接口和性能,涵盖3D图形、音频、网络及设备访问API,如相机和GPS。是构建高效iOS应用的基础,对开发者至关重要。
11 0
|
21天前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
2月前
|
监控 API Swift
用Swift开发iOS平台上的上网行为管理监控软件
在当今数字化时代,随着智能手机的普及,人们对于网络的依赖日益增加。然而,对于一些特定场景,如家庭、学校或者企业,对于iOS设备上的网络行为进行管理和监控显得尤为重要。为了满足这一需求,我们可以利用Swift语言开发一款iOS平台上的上网行为管理监控软件。
196 2
|
安全 测试技术 调度
iOS开发多线程篇-NSThread
上篇我们学习了iOS多线程解决方式中的NSOperation,这篇我主要概况总结iOS多线程中NSThread的解决方式和基本用例
|
缓存 程序员 调度
iOS开发多线程篇-GCD
上篇文章介绍了多线程是什么、线程的进程的区别,在这篇文章中,主要介绍iOS开发中多线程GCD的使用方式和注意事项,同时会给出几种多线程的案例。
|
调度 iOS开发
iOS开发多线程篇-概述
iOS开发多线程篇<概述>