ios側(cè)滑菜單控件

先上效果圖把:


左側(cè)拖動.gif

![右側(cè)點擊.gif](http://upload-images.jianshu.io/upload_images/1249505-2b9771b56dc93e1e.gif?imageMogr2/auto-orient/strip)

項目有這個需求,之前是別人做的效果不太好利耍,后來需要重寫,但還是不是我負責盔粹,但是那段時間不算很忙隘梨,也用自己的思路嘗試著寫了一下,實現(xiàn)的效果很差舷嗡。
現(xiàn)在這個完成效果是項目組的主程寫的轴猎,最近有空看了一下代碼,然后自己模仿著重寫了一下进萄。

看完代碼捻脖,其實實現(xiàn)思路很簡單
1.在控制器中添加三個UIView,分別用來放三個子控制器垮斯;
2.為view添加panGesture,在手勢的delegate中獲取位移來處理界面變化郎仆;
3.利用UIView的transform屬性來實現(xiàn)界面的變化和移動。

關(guān)于transform屬性,是用矩陣乘法對界面進行位移兜蠕,旋轉(zhuǎn)扰肌,放大縮小等,其實可以簡單理解為基于參考坐標系做出一系列變化:

CGAffineTransformRotate // 旋轉(zhuǎn)
CGAffineTransformScale // 放大縮小
CGAffineTransformTranslate // 位移

基本思路就是這樣熊杨,接下來是具體實現(xiàn):

1.初始化方法:
- (instancetype)initWithMainViewController:(UIViewController *)mainVC
leftViewController:(UIViewController *)leftVC
rightViewController:(UIViewController *)rightVC
{
self = [super init];

      if (self) {
        [self prepare];
        self.mainViewController = mainVC;
        self.leftViewController = leftVC;
        self.rightViewController = rightVC;
    }
    return self;
}

2.初始化界面:
為控制器添加_leftContainerView,_rightContainerView及_mainContainerView,在leftViewController的setter方法中做一些設(shè)置曙旭,配置界面的默認位置及大小等:
- (void)setLeftViewController:(UIViewController *)leftViewController
{
if (!leftViewController) {
return;
}
_canShowLeft = YES;
_leftViewController = leftViewController;

    _leftViewController.view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
    [self addChildViewController:leftViewController];
    [_leftContainerView addSubview:leftViewController.view];
    _leftContainerView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -leftShowWidth, 0);
    _leftContainerView.transform = CGAffineTransformScale(_leftContainerView.transform, leftScale, leftScale);
}

此處使用的參數(shù)為預(yù)先設(shè)置好的,可以修改leftScale或rightScale晶府,改變?yōu)閳D1或圖3的顯示效果:
#pragma mark ---------- left config -----------
static CGFloat const leftShowWidth = 240.f;
static CGFloat const leftScale = 0.8f; // 縮放比例
static CGFloat const leftDragbleWidth = 80.f; // 左側(cè)可拖動寬度
static CGFloat const leftMinDragLength = 100.f; //觸發(fā)所需要拖動的最短距離

3.做好界面默認配置以后桂躏,需要的就是添加Pan手勢,并做處理川陆,
此處只表述思路剂习,實際代碼復(fù)雜的多
- (void)panGestureHandler:(UIPanGestureRecognizer *)gesture
{
CGPoint point = [gesture locationInView:self.view];

    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
        {
          // 記錄拖拽的起點
            _startDragPoint = point;
            _lastDragPoint = point;
        }
        break;
        case UIGestureRecognizerStateChanged:
        {
             CGFloat move_length = point.x - _lastDragPoint.x;
             CGFloat scale = 1;
              _lastDragPoint = point;
            // 進行判斷是呼出哪邊的界面  此處寫呼出左側(cè)界面
              scale = 1-(move_length/leftShowWidth)*(1-leftScale);
                    
            // 根據(jù)拖拽移動的距離進行界面的變化
              _mainContainerView.transform = CGAffineTransformTranslate(_mainContainerView.transform, move_length, 0);
              _mainContainerView.transform = CGAffineTransformScale(_mainContainerView.transform, scale, scale);
                    
              CGFloat left_scale = 1+(move_length/leftShowWidth)*(1-leftScale);
              _leftContainerView.transform = CGAffineTransformTranslate(_leftContainerView.transform, move_length, 0);
              _leftContainerView.transform = CGAffineTransformScale(_leftContainerView.transform, left_scale, left_scale);                 
        }
        break;
        case UIGestureRecognizerStateEnded:
        {                            
              CGFloat move_length = fabs(point.x - _startDragPoint.x);
              // 判斷拖拽距離是否足夠顯示或隱藏界面 
              // 此處只作為例子,以左側(cè)界面為例子
                if (move_length>leftMinDragLength) {
                    if (_isLeftShow) {
                        [self hideLeft];
                    }else{
                        [self showLeft];
                    }
                }else{
                    if (_isLeftShow) {
                        [self showLeft];
                    }else{
                        [self hideLeft];
                    }
        }
        break;

上述代碼中较沪,進行界面變化前還需增加判斷鳞绕,何時停止變化。

在show和hide方法中尸曼,需要進行動畫duration的計算们何,然后進行界面變化。剩下的基本就是在兩個leftController和rightController中進行界面布局了控轿。

由于使用了多個controller冤竹,所以leftController和rightController的跳轉(zhuǎn)操作要交由mainController的navigationController來進行拂封,代碼中提供了屬性以供跳轉(zhuǎn),若有不同需求鹦蠕,需要重寫此屬性的getter方法冒签。

@property (nonatomic, strong, readonly) UINavigationController *sliderNavigationController;

基本思路就是這樣,比較復(fù)雜的基本上是界面位移縮放比例的換算钟病,需要在GestureChanged狀態(tài)中進行處理镣衡。

github地址

若有BUG或改進方法,歡迎留言或給我發(fā)郵件档悠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市望浩,隨后出現(xiàn)的幾起案子辖所,更是在濱河造成了極大的恐慌,老刑警劉巖磨德,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缘回,死亡現(xiàn)場離奇詭異,居然都是意外死亡典挑,警方通過查閱死者的電腦和手機酥宴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來您觉,“玉大人拙寡,你說我怎么就攤上這事×账” “怎么了肆糕?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長在孝。 經(jīng)常有香客問我诚啃,道長,這世上最難降的妖魔是什么私沮? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任始赎,我火速辦了婚禮,結(jié)果婚禮上仔燕,老公的妹妹穿的比我還像新娘造垛。我一直安慰自己,他們只是感情好涨享,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布筋搏。 她就那樣靜靜地躺著,像睡著了一般厕隧。 火紅的嫁衣襯著肌膚如雪奔脐。 梳的紋絲不亂的頭發(fā)上俄周,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音髓迎,去河邊找鬼峦朗。 笑死,一個胖子當著我的面吹牛排龄,可吹牛的內(nèi)容都是我干的波势。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼橄维,長吁一口氣:“原來是場噩夢啊……” “哼尺铣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起争舞,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤凛忿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后竞川,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體店溢,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年委乌,在試婚紗的時候發(fā)現(xiàn)自己被綠了床牧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡遭贸,死狀恐怖戈咳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壕吹,我是刑警寧澤除秀,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站算利,受9級特大地震影響册踩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜效拭,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一暂吉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缎患,春花似錦慕的、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐浮。三九已至如孝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偷拔。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工破托, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胖腾,地道東北人无午。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像仪际,于是被迫代替她去往敵國和親围小。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容