Вы можете сделать это, добавив расширение к UISegmentedControl
. Попробуйте это.
extension UISegmentedControl {
private func defaultConfiguration(font: UIFont = UIFont.boldSystemFont(ofSize: 12), color: UIColor = UIColor.gray) {
let defaultAttributes = [
NSAttributedStringKey.font.rawValue: font,
NSAttributedStringKey.foregroundColor.rawValue: color
]
setTitleTextAttributes(defaultAttributes, for: .normal)
}
private func selectedConfiguration(font: UIFont = UIFont.boldSystemFont(ofSize: 12), color: UIColor = UIColor.blue) {
let selectedAttributes = [
NSAttributedStringKey.font.rawValue: font,
NSAttributedStringKey.foregroundColor.rawValue: color
]
setTitleTextAttributes(selectedAttributes, for: .selected)
}
private func removeBorder(){
let backgroundImage = getColoredRectImageWith(color: UIColor.white.cgColor, andSize: CGSize(width: self.bounds.size.width, height: self.bounds.size.height), yOffset: 2)
let backgroundImage2 = getColoredRectImageWith(color: UIColor.lightGray.cgColor, andSize: CGSize(width: self.bounds.size.width, height: self.bounds.size.height))
self.setBackgroundImage(backgroundImage2, for: .normal, barMetrics: .default)
self.setBackgroundImage(backgroundImage, for: .selected, barMetrics: .default)
self.setBackgroundImage(backgroundImage, for: .highlighted, barMetrics: .default)
let deviderImage = getColoredRectImageWith(color: UIColor.gray.cgColor, andSize: CGSize(width: 1.0, height: self.bounds.size.height))
self.setDividerImage(deviderImage, forLeftSegmentState: .selected, rightSegmentState: .normal, barMetrics: .default)
defaultConfiguration( color: UIColor.green)
selectedConfiguration(color: UIColor.blue)
}
func addUnderlineForSelectedSegment(){
removeBorder()
let underlineWidth: CGFloat = self.bounds.size.width / CGFloat(self.numberOfSegments)
let underlineHeight: CGFloat = 1.0
let underlineXPosition = CGFloat(selectedSegmentIndex * Int(underlineWidth))
let underLineYPosition = self.bounds.size.height - 2.0
let underlineFrame = CGRect(x: underlineXPosition, y: underLineYPosition, width: underlineWidth, height: underlineHeight)
let topUnderline = UIView(frame: underlineFrame)
topUnderline.backgroundColor = UIColor.gray
topUnderline.tag = 1
topUnderline.frame.origin.y = self.frame.origin.y
self.addSubview(topUnderline)
let bottomUnderline = UIView(frame: underlineFrame)
bottomUnderline.backgroundColor = UIColor.gray
bottomUnderline.tag = 2
bottomUnderline.frame.origin.x = topUnderline.frame.maxX
self.addSubview(bottomUnderline)
}
func changeUnderlinePosition(){
guard let topUnderline = self.viewWithTag(1) else {return}
let topUnderlineFinalXPosition = (self.bounds.width / CGFloat(self.numberOfSegments)) * CGFloat(selectedSegmentIndex)
topUnderline.frame.origin.x = topUnderlineFinalXPosition
guard let bottomUnderline = self.viewWithTag(2) else {return}
let underlineFinalXPosition = (selectedSegmentIndex == 0) ? topUnderline.frame.maxX : self.frame.origin.x
bottomUnderline.frame.origin.x = underlineFinalXPosition
}
private func getColoredRectImageWith(color: CGColor, andSize size: CGSize,yOffset:CGFloat = 0, hOffset:CGFloat = 0) -> UIImage{
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let graphicsContext = UIGraphicsGetCurrentContext()
graphicsContext?.setFillColor(color)
let rectangle = CGRect(x: 0.0, y: 0.0 + yOffset, width: size.width, height: size.height - hOffset)
graphicsContext?.fill(rectangle)
let rectangleImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return rectangleImage!
}
}
Usage
В viewDidLoad
добавить
mySegmentControl.addUnderlineForSelectedSegment()
А в вашем управляющем действии сегмента используйте
@IBAction func mySegmentControl(_ sender: UISegmentedControl) {
mySegmentControl.changeUnderlinePosition()
}