• (二十八)QQ好友列表的展开收缩


    要通过监听HeaderView上面的Button来进行操作:

    通过addTarget方法即可,应该将按钮的点击方法封装在HearView控制器内部。

    列表收起来的原理:

    tableView: numberOfRowsInSection: 方法返回0就是不显示,注意要刷新表格。

    只要在Group模型中定义一个变量表示是否展开:

    /**
     *  是否需要展开
     */
    @property (nonatomic, assign, getter = isExpanded) BOOL expanded;
    然后利用addTarget方法给按钮添加事件:

    [nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];
    实现点击事件:

    - (void)nameViewClick{
        self.group.expanded = !self.group.expanded;
    }
    在控制器内部进行判断和返回:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        
        FriendsGroup *group = self.groups[section];
        return  group.isExpanded ? group.friends.count : 0;
    }

    需要注意的是只有数据刷新的时候才会调用上面的方法,因此在点击按钮时还应该调用tableView的reloadData方法,但是点击事件在HeaderView的控制器里,因此应该tableView控制器监听按钮点击,即称为HeaderView的代理

    设置代理的规范:

    1.声明协议:注意协议名以类名开头,方法名也以类名开头,建议写@option,如果写了@option,一定要在调用代理方法时检查有没有这个方法(respondsTo...方法)。

    @protocol HeaderViewDelegate <NSObject>
    
    @optional
    - (void)headerViewDidClickNameView:(HeaderView *)headerView;
    
    @end

    2.添加代理成员变量:

    @property (nonatomic, weak) id<HeaderViewDelegate> delegate;
    3.更新上面的按钮点击事件,调用代理方法,注意的是检查这个方法有没有被代理实现:一定要用respondsTo...方法检查

    - (void)nameViewClick{
        self.group.expanded = !self.group.expanded;
        
        if ([self.delegate respondsToSelector:@selector(headerViewDidClickNameView:)]) {
            [self.delegate headerViewDidClickNameView:self];
        }
        
    }
    4.tableView控制器遵循protocol(在interface处遵循)。

    5.在新建HeaderView时将delegate设定为自身(self)。

    6.实现这个方法,刷新数据:

    - (void)headerViewDidClickNameView:(HeaderView *)headerView{
        [self.tableView reloadData];
    }


    一个细节:在按钮展开的时候,需要把前面的箭头由向右变为向下,一个直接的思路是在HeaderView的Click方法内进行旋转:

    </pre>注意transfrom属性设置以CGAffine开头,旋转式弧度<pre name="code" class="objc">    if (self.group.isExpanded) {
            self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
        }else{
            self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
        }

    旋转的细节:imageView的旋转是将内容旋转,默认拉伸,如果要让箭头不失真,应该让内容居中不拉伸,为了防止图片显示不全,应该关掉clipToBounds方法:

    nameView.imageView.contentMode = UIViewContentModeCenter;
    nameView.imageView.clipsToBounds = NO;

    这样是无效的,因为在这之后调用了reloadData方法,调用这个方法后加载的HeaderView并不是从缓存池中取得的而是新建的。

    因此应该监听新HeaderView的添加,使用didMoveToSuperview方法或者willMoveToSuperview:(传入要添加的控件)。

    只需要将上面的内容在HeaderView的didMoveToSuperview中实现即可。

    - (void)didMoveToSuperview{
        if (self.group.isExpanded) {
            self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
        }else{
            self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
        }
    }

    Tip:循环利用有时候会引入困扰(修改的内容被新加入的覆盖)。



  • 相关阅读:
    现存的数据库的解决方案的原理解析
    HTTP代理实现请求报文的拦截与篡改
    ucos软件结构
    微软官方Windows 8设计
    asp.net对CNMARC
    jQuery弹出层插件
    从"Hello World!"到面向对象
    git 的使用命令:克隆
    第一个C程序
    云计算平台简介(App Engine)
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154225.html
Copyright © 2020-2023  润新知