图片展示:
目录结构:
定义两个模型:qq分组模型和qq好友模型
定义两个视图:好友展示的cell,和section的headerView
主要代码:
模型代码
class QQFriend:NSObject {
var name:String?
var icon:String?
var intro:String?
var vip:NSNumber?
init(dic:NSDictionary) {
super.init()
self.setValuesForKeysWithDictionary(dic as! [String : AnyObject])
}
}
class QQFriendGroup:NSObject {
var name:String?
var friends:NSArray?
var online:NSNumber?
// 这个变量是控制分组是否打开的,如果打开则设定展示cell的个数
var isOpen:Bool? = false
init(withDic dic:NSDictionary) {
super.init()
self.setValuesForKeysWithDictionary(dic as! [String : AnyObject])
let arrayFriend:NSMutableArray = NSMutableArray()
for friendDic in self.friends! {
let friend :QQFriend = QQFriend.init(dic: friendDic as! NSDictionary)
arrayFriend.addObject(friend)
}
self.friends = arrayFriend
}
}
视图代码
// 自定义的cell
class QQFriendCell: UITableViewCell {
class func cellWithTableView(tableView:UITableView) -> QQFriendCell {
let cellID = "friend"
var cell = tableView.dequeueReusableCellWithIdentifier(cellID)
if cell == nil {
cell = QQFriendCell.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellID)
}
return cell as! QQFriendCell
}
// 每个cell展示的好友信息
var friendData:QQFriend? {
didSet {
self.imageView?.image = UIImage(named: friendData!.icon!)
self.textLabel?.text = friendData!.name!
self.textLabel?.textColor = friendData!.vip == true ? UIColor.redColor() : UIColor.blackColor()
self.detailTextLabel?.text = friendData!.intro!
}
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
##// 自定义section的headerView
// 协议,点击headerView的回调
protocol QQHeaderViewDelegate:NSObjectProtocol {
func headerViewDidClickedNameView(headerView:QQHeaderView)
}
class QQHeaderView: UITableViewHeaderFooterView {
weak var delegate:QQHeaderViewDelegate?
// 显示在线的人数
var countView:UILabel? = {
let countView:UILabel = UILabel.init()
countView.textAlignment = .Center
countView.textColor = UIColor.grayColor()
return countView
}()
// 好友的姓名
var nameView:UIButton? = {
let nameView = UIButton.init(type: UIButtonType.Custom)
nameView.setBackgroundImage(UIImage(named: "buddy_header_bg"), forState: UIControlState.Normal)
nameView.setBackgroundImage(UIImage(named: "buddy_header_bg_highlighted"), forState: UIControlState.Highlighted)
// 设定那个group的小角
nameView.setImage(UIImage(named: "buddy_header_arrow"), forState: UIControlState.Normal)
nameView.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
nameView.contentHorizontalAlignment = .Left
nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0)
nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0)
nameView.imageView?.contentMode = .Center
nameView.imageView?.clipsToBounds = false
return nameView
}()
// headerView根据这个group进行展示分组信息
var group:QQFriendGroup? {
didSet {
self.nameView?.setTitle(group!.name!, forState: UIControlState.Normal)
self.countView?.text = "\(group!.online!)" + "/" + "\(group!.friends!.count)"
didMoveToSuperview()
}
}
// 返回一个headerView
class func headerViewWithTableView(tableView:UITableView) -> QQHeaderView {
let headerID = "myHeader"
var header = tableView.dequeueReusableHeaderFooterViewWithIdentifier(headerID)
if header == nil {
header = QQHeaderView.init(reuseIdentifier: headerID)
}
return header as! QQHeaderView
}
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
self.nameView!.addTarget(self, action: #selector(QQHeaderView.nameClick), forControlEvents: UIControlEvents.TouchUpInside)
self.contentView.addSubview(nameView!)
self.contentView.addSubview(countView!)
}
func nameClick() {
self.group?.isOpen = !self.group!.isOpen!
// 刷新表格
if ((self.delegate?.respondsToSelector(Selector("headerViewDidClickedNameView:"))) != nil) {
self.delegate?.headerViewDidClickedNameView(self)
}
}
// 在父视图上动哈哈
override func didMoveToSuperview() {
super.didMoveToSuperview()
if self.group!.isOpen == true {
self.nameView?.imageView?.transform = CGAffineTransformMakeRotation(CGFloat( M_PI_2))
}else {
self.nameView?.imageView?.transform = CGAffineTransformMakeRotation(0)
}
}
// 设置 nameView 和 在线人数countView 的frame
override func layoutSubviews() {
super.layoutSubviews()
self.nameView?.frame = self.bounds
let countH:CGFloat = self.frame.size.height
let countW:CGFloat = 150
let countY:CGFloat = 0
let countX:CGFloat = self.frame.size.width - 10 - countW
self.countView?.frame = CGRectMake(countX, countY, countW, countH)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
视图控制器代码
class ViewController: UIViewController ,UITableViewDelegate, UITableViewDataSource, QQHeaderViewDelegate{
// 从本地获取模拟数据
lazy var groups:NSArray? = {
let filePath = NSBundle.mainBundle().pathForResource("friends.plist", ofType: nil)
var dicArr:NSArray = NSArray.init(contentsOfFile:filePath!)!
var arr:NSMutableArray = NSMutableArray()
for dic in dicArr {
let group:QQFriendGroup = QQFriendGroup.init(withDic: dic as! NSDictionary)
arr.addObject(group)
}
return arr
}()
var tableView:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
buildTableView()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
// 构建tableview
func buildTableView() {
self.tableView = UITableView.init(frame: self.view.bounds, style: UITableViewStyle.Plain)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = 50
self.tableView.sectionHeaderHeight = 44
self.view.addSubview(self.tableView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// tableView 代理方法
extension ViewController {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.groups!.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let group:QQFriendGroup = self.groups![section] as! QQFriendGroup
return group.isOpen == true ? group.friends!.count : 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = QQFriendCell.cellWithTableView(tableView)
let group = self.groups![indexPath.section] as! QQFriendGroup
cell.friendData = group.friends![indexPath.row] as? QQFriend
return cell
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header:QQHeaderView = QQHeaderView.headerViewWithTableView(tableView)
header.delegate = self
header.group = self.groups![section] as! QQFriendGroup
return header
}
}
// QQ headerView 的代理方法
extension ViewController {
// 每次点击headerView时,改变group的isOpen参数,然后刷新tableview,显示或者隐藏好友信息
func headerViewDidClickedNameView(headerView: QQHeaderView) {
self.tableView.reloadData()
}
}
体会:
1 自定义cell
的时候出了错,返回cell
的时候总是提示我为nil
错误,原来是我在复用获得cell
的时候把cell
强转QQcell
时出的错,改正就是,先从复用池中获得一个不管什么类型的cell
,如果为nil
,就使用我们自己的初始化方法搞出来一个,然后在return
的时候强转。
2这个小例子,主要都在headerView
这块,设置代理,根据获得的数据改变小三角的指向,点击更改group
的isOpen
的状态,这些写好了就能完成这个小demo了。
3在VC中主要就是展示tableview了。