iOS-小demo--簡易的抽屜效果封裝

芙蓉落盡天涵水,日暮滄波起!<藤藤蛇>

效果圖:


簡單側滑抽屜效果封裝.gif

簡單的思路說明:

想要的效果就是, 向右滑動屏幕的時候 左側的視圖(綠色)會隨著拉動出現(xiàn), 同時會有一個透明度的改變! 實現(xiàn)思路大致就是要在最開始的界面(View)上添加平移手勢, 根據(jù)手勢滑動的偏移量來控制左側(綠色)視圖的位置, 同時改變在藍色上面一層的遮擋視圖(紅色)的透明度! 當綠色的菜單欄回去的時候隱藏遮擋的(紅色)視圖. 當綠色菜單在的時候, 點擊紅色視圖,同樣會收起綠色菜單!只需要在遮擋的紅色視圖上添加點擊手勢! 并執(zhí)行響應的操作即可.



上代碼:

定義的宏:

// 屏幕的寬 高
#define kSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define kSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
// 菜單寬度
#define MENU_WIDTH (kSCREEN_WIDTH * 1 / 3)
// 遮擋視圖的顏色
#define MASK_COLOR [UIColor redColor]
// 遮擋的最大透明度
#define MASK_MAX_ALPHA 0.5

定義的相關屬性

// 容納 側滑 的視圖控制器
@property (nonatomic, strong) UIViewController *containerVC;
// 滑動時候 遮蓋 在視圖控制器上的一層 View
@property (nonatomic, strong) UIView *maskView;

1: 初始化方法 這里用單例方法 一般 App 只有一個設置的側滑視圖

// 構造左側  整體的 View 整個工程只有一個 側滑  這里我用了 Xib 主要是容易添加一些想要的效果
+ (instancetype)shareSliderMenuView
{
    static PP_SlideMenuView *slideMenuView = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        slideMenuView = [[NSBundle mainBundle] loadNibNamed:@"PP_SlideMenuView" owner:self options:nil].firstObject;
        slideMenuView.frame = CGRectMake(- MENU_WIDTH, 0, MENU_WIDTH, kSCREEN_HEIGHT);
    });
    return slideMenuView;
}

2: 綁定控制器確定在哪里展示 主要是為了封裝

// 綁定控制器 并進行相關的設置
- (void)bindWithViewController:(UIViewController *)rootVc
{
    __weak UIViewController *tempVc = rootVc;
        self.containerVC = tempVc;// 設置為視圖的一個屬性方便在不同地方使用
        self.isMenuViewHidden = YES;// 記錄開始狀態(tài)為 隱藏菜單視圖
        // 創(chuàng)建遮擋的 View
        self.maskView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _maskView.backgroundColor = MASK_COLOR;
        _maskView.hidden = YES; // 只有在滑動菜單出現(xiàn)時候才會  出現(xiàn) MaskView 遮擋
        [_containerVC.view addSubview:_maskView]; // 遮擋的 加到 控制器 view 上
        
        // 使用 KVO 監(jiān)控 菜單View 的位置變化  然后改變遮擋視圖的 透明度
        [self addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
        // 給視圖控制器上的  View 添加平移 手勢 以及 遮擋的 MaskView 加點擊手勢
        [self addOurGestureRecognizer]; 
}```
```code

#pragma mark ------>> 給視圖控制器上的  View 添加平移 手勢 以及 遮擋的 MaskView 加點擊手勢 <<------
- (void)addOurGestureRecognizer
{
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panContainViewAction:)]; // 右滑動時候  出來菜單
    pan.delegate = self;
    [_containerVC.view addGestureRecognizer:pan];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHiddenMenuAction:)]; // 要是菜單在  點擊 MaskView 隱藏菜單
    [_maskView addGestureRecognizer:tap];

}
#pragma mark ------>> 滑動視圖控制器的 View 的時候觸發(fā)方法 <<------
- (void)panContainViewAction:(UIPanGestureRecognizer *)pan
{
    // 偏移量
    CGPoint offSet = [pan translationInView:_containerVC.view];
    // 平移進行時候
    if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)
    {
        if (offSet.x > 0)//向右滑動
        {
            if (self.frame.origin.x == 0)
            {
                return;
            }
            CGFloat tempX = self.frame.origin.x + offSet.x;// 算出更新的 x
            if (tempX <= 0 )
            {// 小于 0 就隨著拖動移動就好
                self.frame = CGRectMake(tempX, 0, MENU_WIDTH, kSCREEN_HEIGHT);
            }else
            {// 都出來之后 就讓它完全展示就好  別滑到太靠右地方
                self.frame = CGRectMake(0, 0, MENU_WIDTH, kSCREEN_HEIGHT);
            }
        }else
        {// 向左滑動
            CGFloat tempX = self.frame.origin.x + offSet.x;// 算出更新的 x
            self.frame = CGRectMake(tempX, 0, MENU_WIDTH, kSCREEN_HEIGHT);
        }
    }else
    {// 在這里判斷要 顯示還是隱藏
        if (self.frame.origin.x >= - MENU_WIDTH * 0.5)
        {
            [self inputOfSightMenuView];
        }else
        {
            [self outOfSightMenuView];
        }
    }
    // 清除偏移量
    [pan setTranslation:(CGPointZero) inView:_containerVC.view];
    //self.maskView.frame = CGRectMake(CGRectGetMaxX(self.frame), 0, kSCREEN_WIDTH, kSCREEN_HEIGHT);
}

// 點擊遮擋  收起菜單
- (void)tapHiddenMenuAction:(UITapGestureRecognizer *)tap
{
    [self outOfSightMenuView];
}

#pragma mark ------>> MenuView 視圖 移出 或者 移進 視線  <<------
// 放到視線之外
- (void)outOfSightMenuView
{
    [UIView animateWithDuration:0.2 animations:^{
        self.frame = CGRectMake(- MENU_WIDTH, 0, MENU_WIDTH, kSCREEN_HEIGHT);
        self.isMenuViewHidden = YES;
        self.maskView.hidden = YES;
    }];
}
// 放到視線之內
- (void)inputOfSightMenuView
{
    [UIView animateWithDuration:0.2 animations:^{
        self.frame = CGRectMake(0, 0, MENU_WIDTH, kSCREEN_HEIGHT);
    } completion:^(BOOL finished) {
        self.maskView.hidden = NO;
        self.maskView.alpha = MASK_MAX_ALPHA;
    }];

}

#pragma mark ------>> KVO 監(jiān)控 菜單View 的位置變化 <<------
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"frame"])
    {
        CGRect newFrame = [change[@"new"] CGRectValue];
        CGFloat newFrameX = newFrame.origin.x;
        // 判斷是否需要改變 遮擋的透明度
        if (newFrameX != - MENU_WIDTH)
        {
            _maskView.hidden = NO;// 出現(xiàn)遮擋
            // 改變遮擋的透明度
            _maskView.alpha = (newFrameX + MENU_WIDTH) / MENU_WIDTH * MASK_MAX_ALPHA;
        }else
        {
            _maskView.hidden = YES;
        }
    }
}

#pragma mark ------>> 手勢沖突時候 調用的手勢代理 <<------
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([otherGestureRecognizer.view isKindOfClass:[UITableView class]]) {
        return NO;
    }
    return YES;
}

最后 在控制器調用

PP_SlideMenuView *slidetView = [PP_SlideMenuView shareSliderMenuView];
   
 [slidetView bindWithViewController:self];

 [self.view addSubview:slidetView];

PS: 最近忙著寫點小項目,哪里寫錯了還請見諒!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末井佑,一起剝皮案震驚了整個濱河市吞鸭,隨后出現(xiàn)的幾起案子色难,更是在濱河造成了極大的恐慌另伍,老刑警劉巖燕侠,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畏腕,死亡現(xiàn)場離奇詭異乘凸,居然都是意外死亡熙兔,警方通過查閱死者的電腦和手機悲伶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來住涉,“玉大人麸锉,你說我怎么就攤上這事∮呱” “怎么了花沉?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長媳握。 經(jīng)常有香客問我碱屁,道長,這世上最難降的妖魔是什么蛾找? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任娩脾,我火速辦了婚禮,結果婚禮上打毛,老公的妹妹穿的比我還像新娘柿赊。我一直安慰自己,他們只是感情好幻枉,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布碰声。 她就那樣靜靜地躺著,像睡著了一般熬甫。 火紅的嫁衣襯著肌膚如雪胰挑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天椿肩,我揣著相機與錄音瞻颂,去河邊找鬼。 笑死郑象,一個胖子當著我的面吹牛贡这,可吹牛的內容都是我干的。 我是一名探鬼主播扣唱,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼藕坯,長吁一口氣:“原來是場噩夢啊……” “哼团南!你這毒婦竟也來了?” 一聲冷哼從身側響起炼彪,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吐根,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辐马,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拷橘,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年喜爷,在試婚紗的時候發(fā)現(xiàn)自己被綠了冗疮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡檩帐,死狀恐怖术幔,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情湃密,我是刑警寧澤诅挑,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站泛源,受9級特大地震影響拔妥,放射性物質發(fā)生泄漏。R本人自食惡果不足惜达箍,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一没龙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缎玫,春花似錦硬纤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伐蒂。三九已至煞躬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逸邦,已是汗流浹背恩沛。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缕减,地道東北人雷客。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像桥狡,于是被迫代替她去往敵國和親搅裙。 傳聞我的和親對象是個殘疾皇子皱卓,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件部逮、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,119評論 4 61
  • 錢鐘書在《圍城》里說:“做媒和做母親是女人的兩個基本愿望÷停” 就做母親來說傅事,我非常贊同。 做媒峡扩,我雖從不曾覺得是愿...
    婭立閱讀 264評論 2 1
  • 寫下的字 落下的淚 在心頭輾轉 丟掉的傘 忘記的路 在身旁消散 手機里你說過的話 仿佛還在耳邊繾綣 曾經(jīng) 蔚藍的不...
    雨淮津河閱讀 403評論 2 1