继承UIControl
class Slider: UIControl {
let trackView = UIView()
var minValue: CGFloat = 0
var maxValue: CGFloat = 1
var currentValue: CGFloat = 0.5 {
didSet {
// self.sendActionsForControlEvents(.ValueChanged)
self.setNeedsLayout()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(trackView)
self.backgroundColor = UIColor.cyanColor()
trackView.backgroundColor = UIColor.redColor()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addSubview(trackView)
self.backgroundColor = UIColor.cyanColor()
trackView.backgroundColor = UIColor.redColor()
}
func moveTrack(touches: NSSet) {
let touch = touches.anyObject() as! UITouch
let location = touch.locationInView(self)
currentValue = (location.x / self.frame.size.width) * (maxValue - minValue) + minValue
}
//开始触摸
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("begin")
moveTrack(touches)
}
//移动
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("continue")
moveTrack(touches)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("end")
//触发事件
self.sendActionsForControlEvents(.ValueChanged)
}
override func layoutSubviews() {
super.layoutSubviews()
let width = (currentValue - minValue) * self.frame.size.width / (maxValue - minValue)
let rect = CGRect(x: 0, y: 0, width: width, height: self.frame.size.height)
trackView.frame = rect
}
}
{
let slider = ProtocolSlider(frame: CGRect(x: 100, y: 100, width: 200, height: 50))
slider.addTarget(self, action: #selector(didChange(_:)), forControlEvents: .ValueChanged)
self.view.addSubview(slider)
}
协议和闭包方法封装
//协议的优点:明确
//协议的缺点:复杂,步骤太多
//如果有optional方法,必须使用@objc
@objc protocol ProtocolSliderDelegate {
optional func didChange(slider: ProtocolSlider)
}
class ProtocolSlider: UIView {
let trackView = UIView()
//用于关联两个对象(控件与需要获取事件的对象)
var delegate: ProtocolSliderDelegate!
var didChange: ((ProtocolSlider) -> Void)!
var minValue: CGFloat = 0
var maxValue: CGFloat = 1
var currentValue: CGFloat = 0.5 {
didSet {
// self.sendActionsForControlEvents(.ValueChanged)
self.setNeedsLayout()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(trackView)
self.backgroundColor = UIColor.cyanColor()
trackView.backgroundColor = UIColor.redColor()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addSubview(trackView)
self.backgroundColor = UIColor.cyanColor()
trackView.backgroundColor = UIColor.redColor()
}
func moveTrack(touches: NSSet) {
let touch = touches.anyObject() as! UITouch
let location = touch.locationInView(self)
currentValue = (location.x / self.frame.size.width) * (maxValue - minValue) + minValue
}
//开始触摸
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("begin")
moveTrack(touches)
}
//移动
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("continue")
moveTrack(touches)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
// print("end")
//触发事件
// self.sendActionsForControlEvents(.ValueChanged)
//1. 如果使用协议,需要确保delegate是否为空
//2. 如果方法为optional,需要确保方法是否实现
// if delegate != nil {
// if delegate.didChange != nil {
// delegate.didChange!(self)
// }
// }
if didChange != nil {
didChange(self)
}
}
override func layoutSubviews() {
super.layoutSubviews()
let width = (currentValue - minValue) * self.frame.size.width / (maxValue - minValue)
let rect = CGRect(x: 0, y: 0, width: width, height: self.frame.size.height)
trackView.frame = rect
}
}
{
let slider = ProtocolSlider(frame: CGRect(x: 100, y: 100, width: 200, height: 50))
// slider.delegate = self
// slider.didChange = {
// sender in
// print(sender.currentValue)
// }
//函数:特殊闭包
//闭包:匿名函数
slider.didChange = didChange
slider.didChange = {
print($0.currentValue)
}
self.view.addSubview(slider)
}
func didChange(sender: ProtocolSlider) {
print(sender.currentValue)
}