• 【iOS基础控件


    A.需求
    1.使用plist数据,展示类似QQ好友列表的分组、组内成员显示缩进功能
    2.组名使用Header,展示箭头图标、组名、组内人数和上线人数
    3.点击组名,伸展、缩回好友组
     
    code source: 
     
    B.实现步骤
    1.编写MVC结构
    Image(125)
     
    Image(126)
     
    (1)根据plist文件结构,编写model,使用嵌套型
    Image(127)
     
    Image(128)
     
    复制代码
     1 //
     2 //  FriendGroup.h
     3 //  FriendsList
     4 //
     5 //  Created by hellovoidworld on 14/12/12.
     6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @class Friend;
    12 
    13 @interface FriendGroup : NSObject
    14 
    15 /** 好友组 */
    16 @property(nonatomic, strong) NSArray *friends;
    17 
    18 /** 好友组名 */
    19 @property(nonatomic, copy) NSString *name;
    20 
    21 /** 在线人数 */
    22 @property(nonatomic, assign) int online;
    23 
    24 - (instancetype) initWithDictionary:(NSDictionary *) dictionary;
    25 + (instancetype) friendGroupWithDictionary:(NSDictionary *) dictionary;
    26 
    27 @end
    复制代码
     
    (2)自定义header,用于组名显示,包括了箭头图示、组名、在线人数/组内人数
    Image(129)
     
    a.数据来源:FriendGroup模型
    1 /** 加载数据  */
    2 - (void)setFriendGroup:(FriendGroup *)friendGroup
     
    b.在init方法中header控件的位置尺寸信息并没有初始化,init方法仅仅用于分配内存,所以要使用初始化后的header位置尺寸数据,要在layoutSubviews方法中使用
    复制代码
     1 /** 子控件布局方法 
     2     在init的时候,只分配的内存,没有初始化控件的尺寸,在此处header已经有了位置尺寸了
     3 */
     4 - (void)layoutSubviews {
     5     // 必须先调用父类的方法
     6     [super layoutSubviews];
     7    
     8     // 1.背景
     9     self.headerButtonView.frame = self.bounds;
    10    
    11     // 2.在线人数/组内总人数
    12     CGFloat countWidth = 150;
    13     CGFloat countHeight = self.frame.size.height;
    14     CGFloat countX = self.frame.size.width - 10 - countWidth;
    15     CGFloat countY = 0;
    16     self.onlineCountView.frame = CGRectMake(countX, countY, countWidth, countHeight);
    17 }
    复制代码
     
    c.使用tableView的缓存池,在controller中实现相应dataSource方法
    1 /** 自定义每个section的头部 */
    2 - (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    3     FriendHeader *header = [FriendHeader friendHeaderWithTableView:self.tableView];
    4     header.friendGroup = self.friendGroups[section];
    5     return header;
    6 }
     
    (3)定义cell,用于显示每个好友信息,包括头像、昵称、介绍(签名)
    Image(130)
     
    实现方法跟header差不多
    数据来源:Friend模型
    在这里cell不用计算子控件的位置尺寸,直接使用 UITableViewCellStyleSubtitle类型的cell
    复制代码
     1 /** 自定义构造方法 */
     2 + (instancetype) cellWithTableView:(UITableView *) tableView {
     3     static NSString *ID = @"friendCell";
     4     FriendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
     5    
     6     if (nil == cell) {
     7         cell = [[self alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
     8     }
     9    
    10     return cell;
    11 }
    12 
    13 /** 加载数据 */
    14 - (void)setFriendData:(Friend *)friendData {
    15     _friendData = friendData;
    16    
    17     self.imageView.image = [UIImage imageNamed:friendData.icon];
    18     self.textLabel.text = friendData.name;
    19     self.textLabel.textColor = friendData.isVip?[UIColor redColor]:[UIColor blackColor];
    20     self.detailTextLabel.text = friendData.intro;
    21 }
    复制代码
     
    初步可以显示整个版面:
    Image(131)
     
    2.伸缩组内好友
    (1)在group模型创建一个标识,用来标识此组的好友是否显示
    1 /** 是否伸展显示好友 */
    2 @property(nonatomic, assign, getter=isOpened) BOOL opened;
     
    (2)给header加上点击事件,改变伸展标识
    1         // 1.4点击事件
    2         [headerButtonView addTarget:self action:@selector(headerClicked) forControlEvents:UIControlEventTouchUpInside];
     
    复制代码
     1 /** 点击事件 */
     2 - (void) headerClicked {
     3     // 1.伸展、隐藏组内好友
     4     self.friendGroup.opened = !self.friendGroup.isOpened;
     5    
     6     // 2.刷新tableView
     7     if ([self.delegate respondsToSelector:@selector(friendHeaderDidClickedHeader:)]) {
     8         [self.delegate friendHeaderDidClickedHeader:self];
     9     }
    10 }
    复制代码
     
    (3)给header编写代理协议
    1 @protocol FriendHeaderDelegate <NSObject>
    2 /** header被点击的代理方法 */
    3 @optional
    4 - (void) friendHeaderDidClickedHeader:(FriendHeader *) header;
    5 
    6 @end
     
    (4)viewController根据group模型的伸展标识,判断是否返回当前组的row数
    1 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    2     FriendGroup *group = self.friendGroups[section];
    3     // 先检查模型数据内的伸展标识
    4     return group.isOpened? group.friends.count : 0;
    5 }
     
    (5)使用viewController作为代理,监听header的点击事件,刷新tableView数据
    1 #pragma mark - FriendHeaderDelegate方法
    2 - (void)friendHeaderDidClickedHeader:(FriendHeader *)header {
    3     // 刷新数据
    4     [self.tableView reloadData];
    5 }
     
    Image(132)
     
    3.改变组的伸展标识—箭头朝向
    (1)由于在header的代理中使用了tableView的 reloadData刷新界面和数据,tableView会从新创建所有header,所以在reloadData之前改变header的外观(比如箭头朝向)是没有意义的。
         所以需要修改新创建的header
    复制代码
    1 /**
    2     被加到父控件之前 
    3     由于tableView刷新数据后,所有header会被重新创建,所以要在这里对箭头朝向做出修改
    4 */
    5 - (void)didMoveToSuperview {
    6     // 改变箭头朝向,顺时针旋转90度
    7     CGFloat rotation = self.friendGroup.isOpened? M_PI_2 : 0;
    8     self.headerButtonView.imageView.transform = CGAffineTransformMakeRotation(rotation);
    9 }
    复制代码
     
    (2)使用transform旋转箭头,因为原来的图片大小非正方形而且填充方式是拉伸,需要做一些属性修改
    1         // 改变箭头填充方式为居中
    2         [headerButtonView.imageView setContentMode:UIViewContentModeCenter];
    3         // 不需要裁剪箭头图片的边界
    4         [headerButtonView.imageView setClipsToBounds:NO];
     
    Image(133)
  • 相关阅读:
    排序(六)插入排序
    集合类 collection接口 ArrayList
    面向对象四大特性
    多线程 interrupt()方法
    NIO Channel 管道
    NIOBuffer 缓冲区
    lamdba表达式
    cloneable以及深拷贝和浅拷贝
    Volatile关键字
    线程池
  • 原文地址:https://www.cnblogs.com/kengsir/p/4281833.html
Copyright © 2020-2023  润新知