注:之前写此demo有些仓促,后来发现有一个小bug:就是第一次进行标题轮转的时候,第二个标题会出现两次.现已对demo修复了bug,已用红色标注出修改的地方
之前总是使用别人封装好的类,封装好的功能,但是从来没有过多的考虑别人是如何想的.但是当自己想去封装一个控件或者类的时候,当自己也要反客为主成为类的设计者的时候,却发现自己很多都想不到,自我感觉是自己平时不注意,经验不丰富,搞一个东西没有思想在里面.之前都是为实现这个功能去"封装"一套东西,但是今天才发现这样做是不对的,而是为了以后在其他地方也能用到,为了以后可以因为此扩展其他的功能而去封装.虽然今天的东西可能很多人看起来很简单,但是自我感觉是真的学习了.
直接贴代码:
工具类自定义View:
import UIKit
// 代理 点击某个条目实现相应的操作 这里暂没实现,以后可以扩展
protocol MarqueeViewDelegate:NSObjectProtocol
{
func marqueeView(marqueeView: MarqueeView, didSelectAtIndex index: Int)
}
// 数据源
protocol MarqueeViewDataSource:NSObjectProtocol
{
// 返回条目的个数
func numberOfMarqueeViewContent(marqueeView:MarqueeView)->Int
// 根据条目的索引获得相应的标题
func marqueeView(marqueeView:MarqueeView,contentOfMarqueeViewAtIndex index:Int)->String
}
class MarqueeView: UIView {
// 懒加载
lazy private var labArray = [UILabel]()
private var labWidth:CGFloat = 30
private var marDataSource:MarqueeViewDataSource!
private var index:Int=0
<span style="color:#FF0000;">private var index:Int=2</span>
// getter用来读取变量值,setter用来写入变量值
var marqueeViewDataSource:MarqueeViewDataSource!{
get{
return marDataSource
}
set{
marDataSource=newValue
for(var i=0;i<2;i++)
{
var lab:UILabel!
if labArray.count>i{
lab = labArray[i]
}else{
lab = UILabel(frame: CGRectMake(80, CGFloat(i)*labWidth, 200, labWidth))
lab.font = UIFont.systemFontOfSize(14)
labArray.append(lab)
self.addSubview(lab)
}
lab.text = self.marDataSource?.marqueeView(self, contentOfMarqueeViewAtIndex: i)
}
}
}
var marqueeViewDelegate:MarqueeViewDelegate!
var timer:NSTimer!
override init(frame: CGRect) {
super.init(frame: frame)
self.clipsToBounds = true
timerOn()
}
// 定时器启动
func timerOn()
{
timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "labRoll", userInfo: nil, repeats: true)
//为了防止单线程的弊端,可以保证用户在使用其他控件的时候系统照样可以让定时器运转
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
}
//关闭定时器,并且把定时器设置为nil,这是习惯
func timerOff()
{
if timer!= nil
{
timer.invalidate()
timer=nil
}
}
// 处理定时器方法
func labRoll()
{
UIView.animateWithDuration(1, animations: {
for(var i=0;i<2;i++)
{
// transform 移动
self.labArray[i].transform = CGAffineTransformTranslate(self.labArray[i].transform, 0, -self.labArray[i].frame.size.height)
}
}) { (flag) -> Void in
// self.index % 2 结果0,1
self.labArray[self.index % 2].transform = CGAffineTransformTranslate(self.labArray[self.index % 2].transform, 0, 2*self.labArray[self.index % 2].frame.size.height)
self.labArray[self.index % 2].text=self.marqueeViewDataSource.marqueeView(self, contentOfMarqueeViewAtIndex: (self.index+1)%self.marqueeViewDataSource.numberOfMarqueeViewContent(self))//之前错误写法
self.labArray[self.index % 2].text=self.marqueeViewDataSource.marqueeView(self, contentOfMarqueeViewAtIndex: (self.index)%self.marqueeViewDataSource.numberOfMarqueeViewContent(self))//改正后写法