在另一个线程中,我找到了分段控件下划线的解决方案。
我的问题的重要一行似乎是这一行:
let underlineWidth: CGFloat = self.bounds.size.width / CGFloat(self.numberOfSegments)
事实证明,宽度的计算并不完全正确。由于我总是有 3 个段,因此我希望此值是屏幕宽度的三分之一(无论设备如何(。
在此屏幕截图中,您可以看到应用程序在两个不同的设备上运行:
截图
如您所见,在iPhone 6S上,下划线的宽度略微太大,而在iPhone 8Plus上则太小。
这只能意味着 self.bounds.size.width 不会返回正确的宽度。
分段控件的整个类:
import UIKit
import Foundation
extension UISegmentedControl{
func removeBorder(){
let backgroundImage = UIImage.getColoredRectImageWith(color: UIColor.clear.cgColor, andSize: self.bounds.size)
let backgroundImageTest = UIImage.getColoredRectImageWith(color: UIColor.red.cgColor, andSize: self.bounds.size)
self.setBackgroundImage(backgroundImage, for: .normal, barMetrics: .default)
self.setBackgroundImage(backgroundImageTest, for: .selected, barMetrics: .default)
self.setBackgroundImage(backgroundImage, for: .highlighted, barMetrics: .default)
let deviderImage = UIImage.getColoredRectImageWith(color: UIColor.clear.cgColor, andSize: CGSize(width: 1.0, height: self.bounds.size.height))
self.setDividerImage(deviderImage, forLeftSegmentState: .selected, rightSegmentState: .normal, barMetrics: .default)
self.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.gray], for: .normal)
self.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor(red: 67/255, green: 129/255, blue: 244/255, alpha: 1.0)], for: .selected)
}
func addUnderlineForSelectedSegment(){
removeBorder()
let underlineWidth: CGFloat = self.bounds.size.width / CGFloat(self.numberOfSegments)
let underlineHeight: CGFloat = 2.0
let underlineXPosition = CGFloat(selectedSegmentIndex * Int(underlineWidth))
let underLineYPosition = self.bounds.size.height - 1.0
let underlineFrame = CGRect(x: underlineXPosition, y: underLineYPosition, width: underlineWidth, height: underlineHeight)
let underline = UIView(frame: underlineFrame)
underline.backgroundColor = UIColor(red: 67/255, green: 129/255, blue: 244/255, alpha: 1.0)
underline.tag = 1
self.addSubview(underline)
}
func changeUnderlinePosition(){
guard let underline = self.viewWithTag(1) else {return}
let underlineFinalXPosition = (self.bounds.width / CGFloat(self.numberOfSegments)) * CGFloat(selectedSegmentIndex)
UIView.animate(withDuration: 0.1, animations: {
underline.frame.origin.x = underlineFinalXPosition
})
}
}
extension UIImage{
class func getColoredRectImageWith(color: CGColor, andSize size: CGSize) -> UIImage{
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let graphicsContext = UIGraphicsGetCurrentContext()
graphicsContext?.setFillColor(color)
let rectangle = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
graphicsContext?.fill(rectangle)
let rectangleImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return rectangleImage!
}
}
您可能正在尝试在方法 func viewDidLoad()
中获取维度。尝试在方法中获取确切的尺寸 func viewDidLayoutSubviews()
.
另请参阅此答案
只有在视图呈现后,视图的确切大小才是正确的。在完成此操作之前,视图具有默认大小(例如,在 xib 或序列图像板中(。在viewDidLayoutSubviews()
或viewDidAppear()
/viewWillAppear()
中,大小肯定会被正确计算。