4 // Created by Si MA on 03/01/2015.
5 // Copyright (c) 2015 Si Ma. All rights reserved.
10 protocol SMSegmentDelegate: class {
11 func selectSegment(_ segment: SMSegment)
14 class SMSegment: UIView {
16 weak var delegate: SMSegmentDelegate?
18 fileprivate(set) var isSelected: Bool = false
19 fileprivate var shouldResponse: Bool!
21 var verticalMargin: CGFloat = 5.0 {
23 self.resetContentFrame()
27 var separatorWidth: CGFloat
30 var onSelectionColour: UIColor = UIColor.darkGray {
32 if self.isSelected == true {
33 self.backgroundColor = self.onSelectionColour
37 var offSelectionColour: UIColor = UIColor.white {
39 if self.isSelected == false {
40 self.backgroundColor = self.offSelectionColour
44 fileprivate var willOnSelectionColour: UIColor! {
46 var hue: CGFloat = 0.0
47 var saturation: CGFloat = 0.0
48 var brightness: CGFloat = 0.0
49 var alpha: CGFloat = 0.0
50 self.onSelectionColour.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
51 return UIColor(hue: hue, saturation: saturation*0.5, brightness: min(brightness*1.5, 1.0), alpha: alpha)
55 // Segment Title Text & Colour & Font
58 self.label.text = self.title
60 if let titleText = self.label.text as NSString? {
61 self.labelWidth = titleText.boundingRect(with: CGSize(width: self.frame.size.width, height: self.frame.size.height), options:NSStringDrawingOptions.usesLineFragmentOrigin , attributes: [NSAttributedStringKey.font: self.label.font], context: nil).size.width
67 self.resetContentFrame()
70 var onSelectionTextColour: UIColor = UIColor.white {
72 if self.isSelected == true {
73 self.label.textColor = self.onSelectionTextColour
77 var offSelectionTextColour: UIColor = UIColor.darkGray {
79 if self.isSelected == false {
80 self.label.textColor = self.offSelectionTextColour
84 var titleFont: UIFont = UIFont.systemFont(ofSize: 17.0) {
86 self.label.font = self.titleFont
88 if let titleText = self.label.text as NSString? {
89 self.labelWidth = titleText.boundingRect(with: CGSize(width: self.frame.size.width + 1.0, height: self.frame.size.height), options:NSStringDrawingOptions.usesLineFragmentOrigin , attributes: [NSAttributedStringKey.font: self.label.font], context: nil).size.width
95 self.resetContentFrame()
100 var onSelectionImage: UIImage? {
102 if self.onSelectionImage != nil {
103 self.resetContentFrame()
105 if self.isSelected == true {
106 self.imageView.image = self.onSelectionImage
107 self.imageView.contentMode = .center
111 var offSelectionImage: UIImage? {
113 if self.offSelectionImage != nil {
114 self.resetContentFrame()
116 if self.isSelected == false {
117 self.imageView.image = self.offSelectionImage
118 self.imageView.contentMode = .center
124 override var frame: CGRect {
126 self.resetContentFrame()
129 fileprivate var imageView: UIImageView = UIImageView()
130 fileprivate var label: UILabel = UILabel()
131 fileprivate var labelWidth: CGFloat = 0.0
133 required init?(coder aDecoder: NSCoder) {
134 fatalError("init(coder:) has not been implemented")
137 init(separatorWidth: CGFloat, verticalMargin: CGFloat, onSelectionColour: UIColor, offSelectionColour: UIColor, onSelectionTextColour: UIColor, offSelectionTextColour: UIColor, titleFont: UIFont) {
139 self.separatorWidth = separatorWidth
140 self.verticalMargin = verticalMargin
141 self.onSelectionColour = onSelectionColour
142 self.offSelectionColour = offSelectionColour
143 self.onSelectionTextColour = onSelectionTextColour
144 self.offSelectionTextColour = offSelectionTextColour
145 self.titleFont = titleFont
147 super.init(frame: CGRect.zero)
148 self.setupUIElements()
151 func setupUIElements() {
153 self.backgroundColor = self.offSelectionColour
155 self.imageView.contentMode = UIViewContentMode.scaleAspectFit
156 self.addSubview(self.imageView)
158 self.label.textAlignment = NSTextAlignment.center
159 self.label.font = self.titleFont
160 self.label.textColor = self.offSelectionTextColour
161 self.addSubview(self.label)
165 func setSelected(_ selected: Bool) {
166 if selected == true {
167 self.isSelected = true
168 self.backgroundColor = self.onSelectionColour
169 self.label.textColor = self.onSelectionTextColour
170 self.imageView.image = self.onSelectionImage
173 self.isSelected = false
174 self.backgroundColor = self.offSelectionColour
175 self.label.textColor = self.offSelectionTextColour
176 self.imageView.image = self.offSelectionImage
180 // MARK: Update Frame
181 fileprivate func resetContentFrame() {
183 var distanceBetween: CGFloat = 0.0
184 var imageViewFrame = CGRect(x: 0.0, y: self.verticalMargin, width: 0.0, height: self.frame.size.height - self.verticalMargin*2)
186 if self.onSelectionImage != nil || self.offSelectionImage != nil {
187 // Set imageView as a square
188 imageViewFrame.size.width = self.frame.size.height - self.verticalMargin*2
189 distanceBetween = 5.0
192 // If there's no text, align imageView centred
193 // Else align text centred
194 if self.labelWidth == 0.0 {
195 imageViewFrame.origin.x = max((self.frame.size.width - imageViewFrame.size.width) / 2.0, 0.0)
198 imageViewFrame.origin.x = max((self.frame.size.width - imageViewFrame.size.width - self.labelWidth) / 2.0 - distanceBetween, 0.0)
201 self.imageView.frame = imageViewFrame
203 self.label.frame = CGRect(x: imageViewFrame.origin.x + imageViewFrame.size.width + distanceBetween, y: self.verticalMargin, width: self.labelWidth, height: self.frame.size.height - self.verticalMargin * 2)
206 // MARK: Handle touch
207 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
208 super.touchesBegan(touches, with: event)
210 if self.isSelected == false {
211 self.shouldResponse = true
212 self.backgroundColor = self.willOnSelectionColour
216 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
217 super.touchesEnded(touches, with: event)
219 self.delegate?.selectSegment(self)