隨便吧,(反正是關于UITableView的)

我還真不知道該怎么介紹這一節所要給大家寫的東西, 就感覺突然想寫,就把他寫下來了。 好了,先看一下效果圖吧。
(這里我主要事項介紹一種思想,模仿蘋果的思想.)

可不是介紹美團哦.gif
  1. 我主要想介紹的是,雙排 tableView 的顯示界面.以及關于自定義控件仿 tableView和代碼擴展性的介紹.
    1.1 閑話少說,要展示雙排 tableView,自定義 view,xib 中加入兩個 tableView 并添加約束
    1.2 拖線,這里我們姑且將 view 稱為 leftRightView, 左邊的 tableView稱為 leftTableView, 右邊的 tableView 稱為 rightTableView. 將左右兩邊的 tableView 的 dataSource (數據源)和 delegate(代理)都托給 leftRightView(其實在我看來這里的 leftRightView 就是一個容器 view, 就是為放東西的).

  2. 現在是關鍵的時候,理解好的話,也許會對你的 tableView 有更深的印象.
    2.1 我們之前說過要封裝一個和 tableView 一樣的控件,這樣的我們就會想到, tableView 的數據和事件都是怎么處理的. 很簡單,答案就是他們的數據源和代理提供和執行的.
    2.2 那,我們就給自己的 leftRightView 書寫數據源方法和代理方法,然后讓成為我們數據源和代理的對象,給我提供數據,以及事件的處理.
    2.3 大家就會想那內部怎么辦呢, leftRightView 內部怎么辦呢.
    2.3.1 怎么辦? 有數據的話,那數據個數不就知道了,有數據的話,展示什么的不就也知道了. 第二排得數據,是根據點擊第一排數據的得到了.(想到了點擊,就想到了代理方法了. )(給傳入點擊的行,返回數組數據, 有數據,再進行添加就行了).

3.也許大家還是不太明白, 在這里我講方法書寫一下,也許大家就會懂了.
3.1 數據源方法

// 數據源的方法
@class LXLLeftRightView;
@protocol LXLLeftRightViewDataSource<NSObject>
// 必須實現的方法
@required
/**
 *  返回左邊的 tableView 的數據個數
 *
 *  @param leftRightView 模仿蘋果將對象傳入
 *
 *  @return 數據個數.
 */
- (NSInteger)numberForItemsForleftRightView:(LXLLeftRightView *)leftRightView;
/**
 *  返回左邊每一行的 tableView 的展示文字
 *
 *  @param leftRightView 模仿蘋果將對象傳入
 *  @param row           行號
 *
 *  @return 返回字符串(文字)
 */
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView nameForRow:(NSInteger)row;
// 可選實現的方法
@optional
/**
 *  返回左邊每一行的 左邊圖片名字(看你模型中是否有這種屬性)
 *
 *  @param leftRightView 模仿蘋果將對象傳入
 *  @param row           行號
 *
 *  @return 返回圖片名字
 */
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView imageNameForRow:(NSInteger)row;
/**
 *  返回左邊每一行的 左邊 cell 點擊后的高亮圖片(看你模型中是否有這一個屬性)
 *
 *  @param leftRightView 模仿蘋果將對象傳入
 *  @param row           行號
 *
 *  @return  返回圖片名字
 */
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView highLightImageNameForRow:(NSInteger)row;
@end

3.2 代理方法

// 代理方法
@protocol LXLLeftRightViewDelegate <NSObject>

@optional
/**
 *  返回點擊了左邊leftTableView的某一行的 的數組數據,用于放置在右邊rightTableView的 cell 種
 *
 *  @param leftRightView  模仿蘋果將對象傳入
 *  @param row           行號
 *
 *  @return 返回數組數據
 */
- (NSArray *)leftRightView:(LXLLeftRightView *)leftRightView didSelectRow:(NSInteger)row;
@end

3.3 先看看 leftRightView 內部是怎么給布置數據的

#pragma mark - 數據源方法
// 根據 tableView 的不同 ,來返回不同的行數.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.leftTableView) {
        // 這里為什么不實現 [self.dataSoure respondsToSelector:<#(SEL)#>]方法,是因為這個方法是必須實現的,你要作我的數據源,就必須要實現我的方法
// 數據源執行方法,返回數據個數
           return  [self.dataSoure numberForItemsForleftRightView:self];
    }else{
// 點擊 左邊 tableView 返回的數組數據(這里也是我原本模型中有的數據類型)
        return self.subArray.count;
    }
}

// 根據tableView 的不同,來展示 cell 的數據
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = nil;
// 這里我自定義了 cell, 當然你也可以自定義,或者 注冊都可以的
    if (tableView == self.leftTableView) {
        cell = [LXLLeftRightCell leftRightCellWithtableView:tableView withReusableIdentifier:ID withStyle:UITableViewCellStyleDefault];
// 這里也是必須實現的方法, 用來返回左邊 cell 的展示文字
            cell.textLabel.text = [self.dataSoure leftRightView:self nameForRow:indexPath.row];
// 這里為可選方法,由于設定左邊 cell 的顯示圖片和選中圖片
        if ([self.dataSoure respondsToSelector:@selector(leftRightView:imageNameForRow:)]) {
            NSString *imageName = [self.dataSoure leftRightView:self imageNameForRow:indexPath.row];
            cell.imageView.image = [UIImage imageNamed:imageName];
        }
        if ([self.dataSoure respondsToSelector:@selector(leftRightView:highLightImageNameForRow:)]) {
            NSString *highLightImageName = [self.dataSoure leftRightView:self highLightImageNameForRow:indexPath.row];
            cell.imageView.highlightedImage = [UIImage imageNamed:highLightImageName];
        }
    }else{
        cell = [LXLLeftRightCell leftRightCellWithtableView:tableView withReusableIdentifier:ID withStyle:UITableViewCellStyleDefault];
// 根據返回的數組數據,給右邊的 tableView 賦值
              cell.textLabel.text = self.subArray[indexPath.row];
    }
    return cell ;
}

3.4 點擊左邊 cell 的 代理方法的實現

#pragma mark - 代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 點擊了左邊 tableView 的 cell
    if (tableView == self.leftTableView) {
// 如果實現了代理方法
        if ([self.delegate respondsToSelector:@selector(leftRightView:didSelectRow:)]) {
// 返回一組數組(用于布置右邊 tableView 的 顯示)           
 self.subArray = [self.delegate leftRightView:self didSelectRow:indexPath.row];
// 刷新右邊 tableView 的控件(如果不刷新,就不會顯示. 因為數據源方法,不會執行,這里的刷新是用來強制執行數據源方法的)
            [self.rightTableView reloadData];
        }
    }
}

4.如果大家看懂了上面幾個方法的實現, 就會明白這個 leftRightView 就相當于一個 tableView, 我不需要知道數據具體是什么,只要設定了數據源對象,和代理對象,讓他提供就行了. 這樣的話,我的控件就獨立出來了, 擴展性就加強了.

5.上面都懂了的話,我覺得下面的代碼,就可以不用看了,跟廢話基本沒區別.(但還是寫寫把,即使是廢話,也是很重要的)
5.1 先讓能提供數據的控制器作為控件的數據源和代理(記得遵守協議哦)

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    LXLLeftRightView *categoryView = [LXLLeftRightView leftRightView];
    categoryView.frame = self.view.bounds;
    [self.view addSubview:categoryView];
    categoryView.delegate = self;
    categoryView.dataSoure = self;
}

5.2 實現對應的方法 (一般數據都是模型數組數據, 這里一般使用懶加載的方式,進行數據加載,主要是想提高啟動效率,以為程序啟動到顯示,肯定要做很多事,如果你讓他啟動的時候就加載數據的話,是很耗性能,耗時也長的, 對于不好的手機,估計直接就死機了,O(∩_∩)O~).

// 數據加載, 這里我用的是 MJExtension 的框架,說真的很好用.但是前提你會模型轉換才行,不要上手就用,而不動其中的運轉機制
#pragma mark - 懶加載
- (NSArray *)categories
{
    if (_categories == nil) {
        _categories = [LXLCategory objectArrayWithFilename:@"categories.plist"];
    }
    return _categories;
}
#pragma mark - 數據源
// 返回左邊 tableView 的行數
- (NSInteger)numberForItemsForleftRightView:(LXLLeftRightView *)leftRightView
{
    return self.categories.count;
}
// 根據行號,取出模型,再返回模型中的 name 屬性文字
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView nameForRow:(NSInteger)row
{
    LXLCategory *category = self.categories[row];
    return category.name;
}
// 根據行號取出模型,返回圖片 name
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView imageNameForRow:(NSInteger)row
{
    LXLCategory *category = self.categories[row];
    return category.small_icon;
}
// 根據行號取出模型,返回高亮圖片 name
- (NSString *)leftRightView:(LXLLeftRightView *)leftRightView highLightImageNameForRow:(NSInteger)row
{
    LXLCategory *category = self.categories[row];
    return category.small_highlighted_icon;
}
#pragma mark - 代理方法
// 根據選中的行號,返回 數組(模型中有的),用來布置右邊的 tableView
- (NSArray *)leftRightView:(LXLLeftRightView *)leftRightView didSelectRow:(NSInteger)row
{
    LXLCategory *category = self.categories[row];
    return category.subcategories;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容