亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS開發之路--仿網易抽屜效果

2020-07-26 03:36:49
字體:
來源:轉載
供稿:網友

最終效果圖:


MainStoryBoard示意圖:


BeyondViewController.h

//// BeyondViewController.h// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <UIKit/UIKit.h>#import "LeftTableViewControllerDelegate.h"@interface BeyondViewController : UIViewController// 左半邊 (顯示 的是欄目列表 )@property (weak, nonatomic) IBOutlet UIView *leftView;// 右半邊 (顯示 的是個人信息設置視圖)@property (weak, nonatomic) IBOutlet UIView *rightView;// 最上面,最大的全屏的是主視圖@property (weak, nonatomic) IBOutlet UIView *mainView;// 上面標題狀態欄視圖中的標題按鈕 (網易的Logo圖片和欄目的名稱 水平排列)@property (weak, nonatomic) IBOutlet UIButton *titleBtn;// mainView的下半部分 是 正文的view,顯示子欄目的view@property (weak, nonatomic) IBOutlet UIView *contentView;// pan 拽 手勢處理- (IBAction)panGesture:(UIPanGestureRecognizer *)sender;// mainView的上半部分 標題狀態欄視圖中的左,右按鈕- (IBAction)btnClick:(UIButton *)sender;@end

BeyondViewController.m

//// BeyondViewController.m// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import "BeyondViewController.h"#import "LeftTableViewController.h"#import "RightViewController.h"#import "Column.h"#import <QuartzCore/QuartzCore.h>// 手勢結束時的x#define kEndX frame.origin.x// 左view的寬度#define kLeftWidth _leftView.frame.size.width// 右view的寬度#define kRightWidth _rightView.frame.size.width// 對協議進行提前聲明@protocol LeftTableViewControllerDelegate ;@interface BeyondViewController ()<LeftTableViewControllerDelegate>{  // 手指按下的時候,記住,mainView的起始x  CGFloat _startX;    // 成員變量,記住左邊控制器的實例  LeftTableViewController *_leftVC;  // 成員變量,記住右邊控制器的實例  RightViewController *_rightVC;      // 字典 ,記住所有實例化了 欄目的子控制器,避免每次都重新創建  NSMutableDictionary *_columnViewControllers;  }@end@implementation BeyondViewController// 隱藏狀態欄- (BOOL)prefersStatusBarHidden{  return YES;}- (void)viewDidLoad{  [super viewDidLoad];    _titleBtn.backgroundColor = [UIColor clearColor];    // 0 字典 ,記住所有實例化了 欄目的子控制器,避免每次都重新創建  _columnViewControllers = [NSMutableDictionary dictionary];    // 0,設置導航條bar的背景 為網 易 紅  //[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"bg.png"] forBarMetrics:UIBarMetricsDefault];  // 狀態條顏色 改成默認的樣式  //[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;    // 1,添加左邊控制器的view到左邊的view里面  _leftVC = [[LeftTableViewController alloc]init];  // 關鍵代碼 為了拿到左邊控制器的某一行被點擊時候,對應的欄目數據模型對象,主控制器成為了左邊控制器的代理,遵守了它定好的協議,實現了協議中的方法,從而拿到左邊控制器被點擊行號對應的數據模型對象  _leftVC.delegate = self;  _leftVC.view.frame = self.leftView.bounds;    [self.leftView addSubview:_leftVC.view];    // 2,同理,添加右邊控制器的view到右邊的view里面	_rightVC = [[RightViewController alloc]init];    _rightVC.view.frame = self.rightView.bounds;    [self.rightView addSubview:_rightVC.view];  // 3,第一次加載時候,就就應該顯示新聞 子欄目的控制器到導航控制器,再將導航控制器的view添加到 mainView里面  [self firstLoading];    }// 自定義方法,第一次加載時候,就就應該顯示新聞 子欄目的控制器到導航控制器,再將導航控制器的view添加到 mainView里面- (void)firstLoading{  Column * column = [Column columnNamed:@"新聞" imgName:@"news.png" className:@"NewsViewController"];    // 僅需手動調用一個 LeftViewController的代理 方法,leftTableViewRowClicked,傳遞一個新聞 子欄目即可  [self leftTableViewRowClicked:column];}// pan 拽 手勢處理- (IBAction)panGesture:(UIPanGestureRecognizer *)sender{    // 如果是剛按下的狀態,則記住,mainView的起始x  if (UIGestureRecognizerStateBegan == sender.state) {    _startX = self.mainView.frame.origin.x;  }      // 平移拖動的距離  CGPoint delta = [sender translationInView:_mainView];    CGRect frame = self.mainView.frame;    // 計算新的x值,并做健壯性判斷  kEndX = _startX + delta.x;    // 1,限制最大拖動范圍    if (kEndX >= kLeftWidth) {    kEndX = kLeftWidth;  }  if (kEndX <= - kRightWidth) {    kEndX = - kRightWidth;  }  // 2,由于 左view和右view在重疊,所以要隱藏其中的一個  if (kEndX > 0) {    // NSLog(@"--調用頻率相當高--");    _rightView.hidden = YES;    _leftView.hidden = NO;  } else {    _rightView.hidden = NO;    _leftView.hidden = YES;  }      if (UIGestureRecognizerStateEnded == sender.state) {        // 手勢結束的時候,需進行robust判斷        // 2,分析end松手時候,的位置x,決定展開到什么程度/*    // 2.1 如果只向右拖了一點點,小于 1/2 的左view的寬度,則歸0    if (kEndX < 0.5*kLeftWidth && kEndX >= 0) {      kEndX = 0;    }else if (kEndX >= 0.5*kLeftWidth && kEndX <= kLeftWidth) {      // 2.2 如果向右拖一大半了,大于 1/2 的左view的寬度,雖然還沒到位,也可以認為是到位了      kEndX = kLeftWidth;    }else if (kEndX > - 0.5*kRightWidth && kEndX <= 0) {      // 2.3 如果只向左拖了一點點,小于 1/2 的右view的寬度,則歸0      kEndX = 0;    }else if (kEndX <= - 0.5*kRightWidth) {      // 2.4 如果向左拖一大半了,大于 1/2 的右view的寬度,雖然還沒到位,也可以認為是到位了      kEndX = - kRightWidth;    }*/            // 第2種判斷方式    // 起始為0,delta.x大于0 代表向右滑動    if (_startX == 0 && delta.x >0) {      kEndX = kLeftWidth;    }else if (_startX == 0 && delta.x < 0){      // 起始為0,delta.x小于0 代表向左滑動      kEndX = - kRightWidth;    }else if (_startX == kLeftWidth && delta.x < 0){      // 起始為kLeftWidth,delta.x小于0 代表向左滑動      kEndX =0;    }else if (_startX == - kRightWidth && delta.x > 0){      // 起始為- kRightWidth,delta.x大于0 代表向右滑動      kEndX = 0;    }          }    // 最后,才設置mainView的新的frame  [UIView animateWithDuration:0.2 animations:^{        self.mainView.frame=frame;  }];        // 最后,為mainView所在的圖層 添加陰影效果  [self addShadowFormainViewWithEndX:kEndX];  }// 自定義方法,為mainView所在的圖層 添加陰影效果 (調用頻率相當高)- (void)addShadowFormainViewWithEndX:(CGFloat)endX{  // 1,點擊工程,加號,導入第3方框架 #import <QuartzCore/QuartzCore.h>    // 2,拿到mainView所在的圖層,設置陰影 參數   // NSLog(@"調用頻率很高---");  _mainView.layer.shadowColor = [UIColor blackColor].CGColor;  _mainView.layer.shadowOpacity = 0.5;  if (endX >= 0) {    _mainView.layer.shadowOffset = CGSizeMake(-5, 0);  } else {    _mainView.layer.shadowOffset = CGSizeMake(5, 0);  }  }// 單擊按鈕,也一樣可以展開 左右側邊欄- (IBAction)btnClick:(UIButton *)sender{  // 定義一個臨時變量  CGFloat startX = _mainView.frame.origin.x;      // 先為mainView所在的圖層 添加陰影效果  [self addShadowFormainViewWithEndX:sender.tag == 1?1:-1];      // 定義一個臨時變量  CGFloat tempEndX = 0;  // 左邊的按鈕被單擊  if (1 == sender.tag) {    // 隱藏右半邊    _leftView.hidden = NO;    _rightView.hidden = YES;        if (startX == 0) {      tempEndX = kLeftWidth;    }else if (startX == kLeftWidth){      tempEndX = 0;    }  } else {    // 單擊右邊按鈕, 隱藏左半邊    _leftView.hidden = YES;    _rightView.hidden = NO;    if (startX == 0) {      tempEndX = - kRightWidth;    }else if (startX == - kRightWidth){      tempEndX = 0;    }  }  // 最后才設置mainView的x,調用抽取出來的公共代碼,設置mainView的x,參數是endX  [self setmainViewX:tempEndX];    }// 抽取出來的公共代碼,設置mainView的x,參數是endX- (void)setmainViewX:(CGFloat)endX{  CGRect frame = self.mainView.frame;  frame.origin.x = endX;  [UIView animateWithDuration:0.2 animations:^{    self.mainView.frame=frame;  }];  }// 最關鍵的方法,左邊控制器的代理 方法,當前左邊控制器中的某一行被點擊的時候 會調用- (void)leftTableViewRowClicked:(id)columnSelected{  Column *column = (Column *)columnSelected;  // 1,關閉左邊的控制=======================  // 調用抽取出來的公共代碼,設置mainView的x,參數是endX  [self setmainViewX:0];        // 2,更改標題按鈕上面的文字  _titleBtn.titleLabel.text = column.columnName;    // 根據欄目數據模型中的類名,實例化對應欄目的控制器,并且將其設置為導航控制器的根控制器,最后將導航控制器的view添加到mainView中,目的是方便設置導航條,以及,各控制器的跳轉      // 2,從緩存字典中取,如果子控制器字典有曾經創建過的子控制器,直接取出來用  UIViewController *columnVC = _columnViewControllers[column.columnClassName];  // 如果子控制器字典中沒有保存過該欄目的控制器,才要創建子控制器  if (columnVC == nil) {    Class c = NSClassFromString(column.columnClassName);    columnVC = [[c alloc]init];    // 并且一定要將其放到 子控制器字典里面,存起來    [_columnViewControllers setObject:columnVC forKey:column.columnClassName];  }      // 4,移除contentView中的正在顯示的舊的子view  if (_contentView.subviews.count > 0) {    UIView *oldView = [_contentView subviews][0];    [oldView removeFromSuperview];  }  // 5,最后將子控制器的view添加到contentView中,顯示  columnVC.view.frame = _contentView.bounds;  [self.contentView addSubview:columnVC.view];  NSLog(@"%@",self.contentView);  // 在添加到mainView之前 ,先得到mainView導航控制器的子控制器,并將其移除(如果有的話),然后才將新的欄目對應的子控制器添加到導航控制器容器中,注意,這兒可以用字典 記住 所有的已經實例化出來 的欄目子控制器,這樣就避免每次都alloc創建新的欄目子控制器,而是只需要根據類名,從字典取出上一次實例化了的同一欄目的子控制器即可  }@end

欄目數據模型Column.h

//// Column.h// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <Foundation/Foundation.h>// 數據模型 代表一個欄目@interface Column : NSObject// 欄目名稱@property (nonatomic,copy)NSString *columnName;// 欄目圖片名稱@property (nonatomic,copy)NSString *columnImgName;// 欄目對應的控制器的類名@property (nonatomic,copy)NSString *columnClassName;// UI控件用weak,字符串用copy,其他對象用strong// 提供一個類方法,即構造函數,返回封裝好數據的對象(返回id亦可)+ (Column *)columnNamed:(NSString *)columnName imgName:(NSString*)columnImgName className:(NSString *)columnClassName;@end

欄目數據模型Column.m

//// Column.m// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.// 數據模型 代表一條欄目#import "Column.h"@implementation Column// 返回一個包含了 欄目對應控制器名字的 對象實例+ (Column *)columnNamed:(NSString *)columnName imgName:(NSString *)columnImgName className:(NSString *)columnClassName{  // 為了兼容子類 使用self  Column *column = [[self alloc]init];  column.columnName = columnName;  column.columnImgName = columnImgName;  column.columnClassName = columnClassName;  return column;}@end

左邊控制器定義好的協議LeftTableViewControllerDelegate.h

//// LeftTableViewControllerDelegate.h// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <Foundation/Foundation.h>#import "Column.h"http:// 左邊控制器 定義的代理/協議 它通過調用自己的成員屬性(即代理)的該方法,將數據傳遞出去(給它的代理去使用) (其實 是主控制器想要數據,所以主控制器在實例化左邊控制器的時候,要設置左邊控制器對應的代理 為 主控制器 自身)@protocol LeftTableViewControllerDelegate <NSObject>- (void)leftTableViewRowClicked:(Column *)columnSelected;@end

LeftTableViewController.h

//// LeftTableViewController.h// 19_抽屜效果_仿網易//// Created by beyond on 14-8-1.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <UIKit/UIKit.h>// 對協議進行提前聲明@protocol LeftTableViewControllerDelegate;@interface LeftTableViewController : UITableViewController// 代理 用weak,防止循環問題,可以是任意類型,但必須遵守協議@property (nonatomic,weak) id<LeftTableViewControllerDelegate> delegate;@end

LeftTableViewController.m

//
//  LeftTableViewController.m
//  19_抽屜效果_仿網易
//
//  Created by beyond on 14-8-1.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
#import "LeftTableViewController.h"
#import "Column.h"
#import "LeftTableViewControllerDelegate.h"
@interface LeftTableViewController ()
{
    // 欄目數組,保存的是左邊欄目列表中的所有欄目對象
    NSArray *_arr;
}
@end
@implementation LeftTableViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // 新聞 欄目
    Column *newsColumn = [Column columnNamed:@"新聞" imgName:@"news.png" className:@"NewsViewController"];
    // 圖片 欄目
    Column *picColumn = [Column columnNamed:@"圖片" imgName:@"pic.png" className:@"PicViewController"];
    // 圖片 欄目
    Column *commentColumn = [Column columnNamed:@"跟帖" imgName:@"comment.png" className:@"CommentViewController"];
    // 以后要添加欄目,只要改這里就可以了
   
   
    // 將欄目對象,一次性全添加到不可變數組中
    _arr = @[newsColumn,picColumn,commentColumn];
   
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _arr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"leftVC";
    // 下面這個dequeue只能用于storyboard或xib中
    // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
    //
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
   
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
   
    // 設置獨一無二的數據
    Column *column = _arr[indexPath.row];
    cell.textLabel.text = column.columnName;
    cell.imageView.image = [UIImage imageNamed:column.columnImgName];
    return cell;
}

// 點擊一行時,主控制中的主視圖必須展示相應欄目的內容,因此,必須實例化對應點擊的行的欄目控制器,并用添加到導航控制器,調用代理 的方法傳遞數據給代理 使用,此處的代理 其實就是 主控制器
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 先取消默認的點擊 高亮的顏色
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    // 取出對應行的數據模型(欄目)
    Column *column = _arr[indexPath.row];
   
    if ([self.delegate respondsToSelector:@selector(leftTableViewRowClicked:)]) {
       
        // 傳遞數據給主控制器 BeyondViewController,通過代理
        // 關鍵代碼~
        [self.delegate leftTableViewRowClicked:column];
    }
   
   
}
@end

RightViewController.xib


NewsViewController.xib


PicViewController.xib


CommentViewController.xib


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av中文字幕在线播放| 2020久久国产精品| 欧美黑人巨大xxx极品| 国产精品mp4| 一区二区国产精品视频| 日韩小视频在线观看| 久久激情五月丁香伊人| 精品国偷自产在线视频99| 91中文在线视频| 亚洲成人免费在线视频| 大荫蒂欧美视频另类xxxx| 国产精品爽黄69| www.xxxx欧美| 伊人久久大香线蕉av一区二区| 日韩成人小视频| 亚洲福利在线视频| 亚洲最大的网站| 亚洲精品xxx| 性夜试看影院91社区| 成人啪啪免费看| 日韩美女福利视频| 视频一区视频二区国产精品| 97碰碰碰免费色视频| 日韩精品视频免费在线观看| 亚洲欧美精品伊人久久| 亚洲另类激情图| 日韩一区在线视频| 久久777国产线看观看精品| 日韩精品中文字幕视频在线| 久久久久久这里只有精品| 久久精品中文字幕免费mv| 亚洲欧美日韩中文在线| 国产精品偷伦一区二区| 欧美成人一区在线| 中文字幕日韩在线观看| 欧美黑人一区二区三区| 91在线|亚洲| 黄色一区二区在线观看| 国产精品入口日韩视频大尺度| 欧美精品情趣视频| www欧美xxxx| 国产精品爽爽爽| 亚洲人成电影在线| 久久久精品在线| 中文字幕精品久久| 91精品国产乱码久久久久久蜜臀| 欧美性jizz18性欧美| 日韩美女视频在线观看| 国产成人精品一区二区| 伊人亚洲福利一区二区三区| 亚洲跨种族黑人xxx| 亚洲自拍另类欧美丝袜| 国产美女精品免费电影| 国产精品黄色影片导航在线观看| 久久久久久久网站| 国模叶桐国产精品一区| 久久国产精品偷| 欧美视频在线观看免费网址| 国内精品模特av私拍在线观看| 亚洲www在线| 国产精品国内视频| 亚洲国产日韩欧美在线图片| 久久久精品2019中文字幕神马| 国产视频久久久久久久| 色偷偷av一区二区三区乱| 欧美亚州一区二区三区| 上原亚衣av一区二区三区| 亚洲日韩欧美视频| 中文字幕精品一区久久久久| 国产精品国产三级国产专播精品人| 91国内产香蕉| 亚洲欧美成人网| 亚洲激情久久久| 欧美日韩国产丝袜另类| 亚洲精品suv精品一区二区| 久久精品电影网| 欧美一区在线直播| 国产97在线观看| 精品国产老师黑色丝袜高跟鞋| 国产精品一区二区三区久久久| 久久九九有精品国产23| 91精品中国老女人| 亚洲国产精品美女| 国产成人精品999| 亚洲开心激情网| 国产精品久久av| 欧美性xxxxhd| 中文字幕在线观看亚洲| 欧美丝袜第一区| 日韩欧美极品在线观看| 日本精品va在线观看| 色偷偷9999www| 国内精品美女av在线播放| 色噜噜狠狠狠综合曰曰曰88av| 欧美亚洲视频在线观看| 日韩欧美视频一区二区三区| 成人精品福利视频| 日本国产欧美一区二区三区| 91影视免费在线观看| 91tv亚洲精品香蕉国产一区7ujn| 成人午夜激情网| 成人免费看吃奶视频网站| 久久在精品线影院精品国产| 亚洲丝袜一区在线| 91精品视频免费| 国产欧美va欧美va香蕉在线| 亚洲无线码在线一区观看| 日韩午夜在线视频| 91av免费观看91av精品在线| 欧美老少配视频| 亚洲国产精品成人va在线观看| 国产亚洲精品一区二555| 精品中文字幕在线| 黑人巨大精品欧美一区二区免费| 久久亚洲精品国产亚洲老地址| 成人在线激情视频| 日韩欧美国产骚| 九九久久综合网站| 日韩av有码在线| 久久在精品线影院精品国产| 欧美成人免费在线视频| 亚洲va久久久噜噜噜| 国产精品一区二区久久| 日韩中文在线中文网三级| 国产成人在线一区| 久久久久久久亚洲精品| 欧美大片va欧美在线播放| 91超碰中文字幕久久精品| 国产在线一区二区三区| 亚洲福利视频久久| 亚洲国产高清自拍| 精品无码久久久久久国产| 影音先锋欧美在线资源| 亚洲视频在线观看免费| 韩国一区二区电影| 日韩高清av在线| 亚洲视频axxx| 国产成+人+综合+亚洲欧洲| 日韩网站免费观看高清| 日韩有码片在线观看| 国产精品久久久久免费a∨大胸| 精品久久久久久亚洲国产300| 亚洲视屏在线播放| 97国产精品免费视频| 91精品国产九九九久久久亚洲| 91精品国产沙发| 韩国19禁主播vip福利视频| 亚洲精品不卡在线| 97在线视频免费看| 国产精品一区二区三区免费视频| 久久艹在线视频| 国产婷婷色综合av蜜臀av| 久久久久久久久久久国产| 国产精品久久久一区| 国产精品99蜜臀久久不卡二区| 日韩中文在线中文网三级| 精品亚洲一区二区| 粉嫩老牛aⅴ一区二区三区| 欧美日本高清视频| 国产亚洲激情在线| 亚洲图片欧美日产| 国产免费一区二区三区香蕉精| 亚洲人成电影网站色www| 麻豆一区二区在线观看|