团购页面模拟,swift版本
继续熟悉UITableView和之前的内容
这个只是模拟一下页面,页面整个就是一个UITableView,UITableView有一个自定义的头和尾,然后就是自定义的cell
需要注意的点:自定义xib,和xib的使用,自定义UITableViewCell,自定义代理协议,dispatch_after的使用
加载数据,注意kvc的读取的数据的键值要与对象的属性名称一致
//
// Goods.swift
// GroupBuying
//
// Created by admin on 16/1/5.
// Copyright © 2016年 jin. All rights reserved.
//
import UIKit
class Goods: NSObject {
var buyCount:NSString!
var icon:NSString!
var price:NSString!
var title:NSString!
//根据文件初始化对象数组
class func instanceWithFile()->[Goods]
{
//读取plist文件内容
let data = NSArray(contentsOfFile: NSBundle.mainBundle().pathForResource("tgs", ofType: "plist")!)
//循环初始化对象数组
var goods:[Goods] = []
for var i = 0;i < data?.count;i++
{
goods.append(self.instanceWithDic(data![i] as! [String : AnyObject]))
}
return goods
}
//根据字典初始化数组
class func instanceWithDic(dic:[String : AnyObject])->Goods
{
let goods = Goods()
//使用kvc赋值
goods.setValuesForKeysWithDictionary(dic)
return goods
}
}
使用xib
自定义cell
,需要注意的是,要在xib的属性里面设置好 Identifier ,不然从缓冲池中取不到内容,依然会重复的创建与销毁对象
//
// GoodsTableCell.swift
// GroupBuying
//
// Created by admin on 16/1/5.
// Copyright © 2016年 jin. All rights reserved.
//
import UIKit
//自定义 UITableViewCell 类
class GoodsTableCell: UITableViewCell {
@IBOutlet weak var title: UILabel!
@IBOutlet weak var price: UILabel!
@IBOutlet weak var buyCount: UILabel!
@IBOutlet weak var icon: UIImageView!
class func instanceWithTableView(tableView:UITableView,goods:Goods)->GoodsTableCell
{
//这个值要和在xib属性栏设置的 Identifier 一致
let id = "goodsTableCell"
//从缓存池中去内容,避免不必要的创建和销毁对象
var temp:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(id)
//因为可能缓存池是空的,取不出内容,所以这里做下处理
if temp == nil
{
temp = NSBundle.mainBundle().loadNibNamed("GoodsTableCell", owner: nil, options: nil).last as! GoodsTableCell
}
//从缓存池取出的是 UITableViewCell 这里需要转换下,方便调用赋值方法
let cell = temp as! GoodsTableCell
//给子控件赋值
cell.setData(goods)
return cell
}
//设置子控件内容
func setData(goods:Goods)
{
self.title.text = goods.title as String
self.price.text = "¥\(goods.price as String)"
self.buyCount.text = goods.buyCount as String + "人购买"
self.icon.image = UIImage(imageLiteral: goods.icon as String)
}
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
}
}
使用xib
自定义footer
,需要注意的是,dispatch_after的使用,和自定义协议
//
// GoodsTableFooter.swift
// GroupBuying
//
// Created by admin on 16/1/5.
// Copyright © 2016年 jin. All rights reserved.
//
import UIKit
//定义代理协议
@objc protocol GoodsTableFooterLoadMoreDataButton:NSObjectProtocol
{
optional func loadmoreDataButton()
}
class GoodsTableFooter: UIView {
@IBOutlet weak var loadMoreButton: UIButton!
@IBOutlet weak var loadMoreView: UIView!
weak var delegate:GoodsTableFooterLoadMoreDataButton!
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
//当从nib文件中初始化称对象时会执行这个方法
override func awakeFromNib() {
super.awakeFromNib()
//设置按钮圆角效果
self.loadMoreButton.layer.cornerRadius = 5
//设置按钮点击事件
loadMoreButton.addTarget(self, action: "loadData:", forControlEvents: UIControlEvents.TouchDown)
}
//快速实例化对象
class func instance()->GoodsTableFooter
{
let footer = NSBundle.mainBundle().loadNibNamed("GoodsTableFooter", owner: nil, options: nil).last as! GoodsTableFooter
return footer
}
//
func loadData(sender:UIButton)
{
//隐藏button按钮,显示菊花
sender.hidden = true
//这里设置下延时执行,之前没用过的一种方式,这个参数有一些特别,而且没有提示。。。。记录下
let minseconds = 2 * Double(NSEC_PER_SEC)
let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
dispatch_after(dtime, dispatch_get_main_queue(), { () -> Void in
let check = self.delegate?.respondsToSelector("loadmoreDataButton")
//因为代理和代理和方法都是可选类型,所以这里需要做下判断是否执行代理方法
if check != nil && (check!) == true
{
self.delegate.loadmoreDataButton!()
}
self.loadMoreButton.hidden = false
})
}
}
使用xib
自定义header
,需要注意的是,因为这个头里面包含一个图片轮播,所以需要用到定时器,scallView代理方法
//
// GoodsTableHeader.swift
// GroupBuying
//
// Created by admin on 16/1/6.
// Copyright © 2016年 jin. All rights reserved.
//
import UIKit
class GoodsTableHeader: UIView,UIScrollViewDelegate {
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
@IBOutlet weak var scallView: UIScrollView!
@IBOutlet weak var pageControl: UIPageControl!
//存放定时器,方便之后的停止
var timer:NSTimer!
//快速实例化的方法
class func instance()->GoodsTableHeader
{
let header = NSBundle.mainBundle().loadNibNamed("GoodsTableHeader", owner: nil, options: nil).last as! GoodsTableHeader
return header
}
//这个方法在xib从文件初始化成对象的时候调用
override func awakeFromNib() {
self.pageControl.numberOfPages = 5
let w = self.scallView.frame.size.width
let h = self.scallView.frame.size.height
let y = self.scallView.frame.origin.y
for var i = 0;i <= self.pageControl.numberOfPages;i++
{
let imageView:UIImageView = UIImageView()
if i == self.pageControl.numberOfPages
{
imageView.image = UIImage(imageLiteral: "ad_" + String(format: "%02i", 0))
}
else
{
imageView.image = UIImage(imageLiteral: "ad_" + String(format: "%02i", i))
}
let x = CGFloat(i) * w
imageView.frame = CGRectMake(x, y, w, h)
self.scallView.addSubview(imageView)
}
self.scallView.contentSize = CGSizeMake(CGFloat(self.pageControl.numberOfPages) * w, h)
self.scallView.pagingEnabled = true
self.scallView.showsHorizontalScrollIndicator = false
self.scallView.delegate = self
self.startTimer()
}
//滚动过程设置 currentPage
func scrollViewDidScroll(scrollView: UIScrollView) {
var currentPage = Int((scallView.contentOffset.x + (0.5 * scallView.frame.size.width)) / scallView.frame.size.width)
if currentPage > self.pageControl.numberOfPages - 1
{
currentPage = 0
}
self.pageControl.currentPage = currentPage
}
//手动拖动时,停止定时器
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
self.timer.invalidate()
}
//手动拖动完毕时,继续定时器
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
self.startTimer()
}
func startTimer()
{
//定时器
self.timer = NSTimer(timeInterval: 2, target: self, selector: "changeImage", userInfo: nil, repeats: true)
let runLoop = NSRunLoop.currentRunLoop()
runLoop.addTimer(self.timer, forMode: NSRunLoopCommonModes)
}
//切换到下一张图片
func changeImage()
{
var offect = CGPointMake(0, 0)
if self.pageControl.currentPage == 0 && self.scallView.contentOffset.x > 0
{
self.scallView.contentOffset = offect
}
offect = CGPointMake(self.scallView.frame.size.width * CGFloat(self.pageControl.currentPage + 1), self.scallView.contentOffset.y)
UIView.animateWithDuration(1, animations: { () -> Void in
self.scallView.contentOffset = offect
})
}
}
在控制器中调用,注意:完成了代理协议之后,要记得设置代理,刷新cell的方式
//
// ViewController.swift
// GroupBuying
//
// Created by admin on 16/1/5.
// Copyright © 2016年 jin. All rights reserved.
//
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,GoodsTableFooterLoadMoreDataButton {
@IBOutlet weak var tableView: UITableView!
lazy var goods:[Goods] = Goods.instanceWithFile()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
//设置cell高度
self.tableView.rowHeight = 150
//设置tableFooter,注意,这里的Footer和代理方法中返回Footer的那个方法设置的Footer可不一样
let footer = GoodsTableFooter.instance()
footer.delegate = self
self.tableView.tableFooterView = footer
//设置header
self.tableView.tableHeaderView = GoodsTableHeader.instance()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.goods.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = GoodsTableCell.instanceWithTableView(self.tableView, goods: self.goods[indexPath.row])
return cell
}
// func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
// var footer:GoodsTableFooter = NSBundle.mainBundle().loadNibNamed("GoodsTableFooter", owner: nil, options: nil).last as! GoodsTableFooter
// return footer
// }
// func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
// return 80
// }
//代理Footer的加载更多数据的方法
func loadmoreDataButton() {
let goods = Goods()
goods.title = "鱼香肉丝"
goods.price = "10"
goods.buyCount = "30"
goods.icon = "37e4761e6ecf56a2d78685df7157f097.png"
//添加数据到cell数据的来源数组
self.goods.append(goods)
//刷新cell,但是这个方法是刷新所有的cell,其实这里只添加了1个数据而已,虽然能达到效果,但是这个不好
// self.tableView.reloadData()
//这个是重新刷新指定的cell,也就是说需要这个行之前就存在,这里加的行在之前是不存在的,所以会报错
// self.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: self.goods.count - 1, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
//这个方法是插入一行,这里用这个最好
self.tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: self.goods.count - 1, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
}
}