如何从分段控件中删除边框
How to remove border from segmented control
如何删除分段控件的外边框?
我已将分隔线图像设置为我想要的,但现在要跟随我的应用程序的模拟,我需要有一个没有外边框的分段控件。
您必须了解的是 backgroundColor
属性 不是有状态的。
因此你必须使用 setBackgroundImage(_:for:barMetrics:)
。
我们可以使用以下函数轻松删除边框和分隔线。
对于 Swift 3 & 4+:
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
对于Swift 2.2:
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(backgroundColor!), forState: .Normal, barMetrics: .Default)
setBackgroundImage(imageWithColor(tintColor!), forState: .Selected, barMetrics: .Default)
setDividerImage(imageWithColor(UIColor.clearColor()), forLeftSegmentState: .Normal, rightSegmentState: .Normal, barMetrics: .Default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image
}
}
调用上面的函数。
segmentedControl.removeBorders()
参考:Remove UISegmentedControl separators completely. (iphone)
感谢 https://whosebug.com/users/3921490/amagain 提供 Swift 3 版本。
这是 Sohil 答案的 swift 3 版本,可能会对其他人有所帮助。它确实帮助了我。 :)
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
如果要保存单元格之间的边框
extension UISegmentedControl {
func removeBorders() {
if let backgroundColor = backgroundColor, let backgroundImage = UIImage.imageWithSize(size: CGSize.one_one, color: backgroundColor){
setBackgroundImage(backgroundImage, for: .normal, barMetrics: .default)
}
if let tintColor = tintColor, let tintImage = UIImage.imageWithSize(size: CGSize.one_one, color: tintColor){
setBackgroundImage(tintImage, for: .selected, barMetrics: .default)
setDividerImage(tintImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
}
extension CGSize{
static var one_one: CGSize{
return CGSize(width: 1.0, height: 1.0)
}
}
extension UIImage{
static func imageWithSize(size : CGSize, color : UIColor = UIColor.white) -> UIImage? {
var image:UIImage? = nil
UIGraphicsBeginImageContext(size)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.addRect(CGRect(origin: CGPoint.zero, size: size));
context.drawPath(using: .fill)
image = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext()
return image
}
}
希望对大家有所帮助
Swift - 4
将 Segment 控件的 Background 颜色和 Tint 颜色设置为相同的颜色。
然后 "set titleTextAttributes" 你的 Segment control
segmentedControl.tintColor = UIColor.red
segmentedControl.backgroundColor = UIColor.red
let attributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
segmentedControl.setTitleTextAttributes(attributes, for: .normal)
segmentedControl.setTitleTextAttributes(attributes, for: .selected)
您可能有不想要圆角边框的用例,因为如果它嵌入在单元格中,您不想看到它。在这种情况下,将自动布局约束设置为 -2 并且边框将被隐藏,因为它会超出单元格边框。
如果您只需要文本段控制,请使用,
segmentControl.backgroundColor = .clear
segmentControl.tintColor = .clear
let attributes: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.white]
segmentControl.setTitleTextAttributes(attributes, for: .normal)
let selectedAttrib: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.red]
segmentControl.setTitleTextAttributes(hightLightedStateAttrib, for: .selected)
注意:我在谷歌上搜索了很长时间,这就是我发布在这里的原因。
来源:CodeMentor
- 已接受的答案适用于消除边框。
- 提到的解决方案here也适用于禁用分段控件。
然而,将两个解决方案放在一起,我无法在 disabled
状态下获得正确的 selected 段。
我想要的是在选择段并进行网络调用时,我想禁用分段控制。
结果是这样的:
想要的是:
的唯一补充是:
setBackgroundImage(imageWithColor(color: imageWithColor(color: tintColor)), for: [.selected, .disabled], barMetrics: .default)
在选择&&禁用后段将具有正确的颜色。
Swift 5.x:
此解决方案仅删除外部边框并保留每个按钮上的圆角
extension UISegmentedControl {
func removeBorders(andBackground:Bool=false) {
setBackgroundImage(imageWithColor(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
_ = self.subviews.compactMap {
if ([=10=].frame.width>0) {
[=10=].layer.cornerRadius = 8
[=10=].layer.borderColor = UIColor.clear.cgColor
[=10=].clipsToBounds = true
[=10=].layer.borderWidth = andBackground ? 1.0 : 0.0
[=10=].layer.borderColor = andBackground ? tintColor?.cgColor : UIColor.clear.cgColor
andBackground ? [=10=].layer.backgroundColor = UIColor.clear.cgColor : nil
}
}
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
用法:
mySegmentedControl.removeBorders()
对我有帮助。
但是如果不设置UIImage
大小,可能会影响UISegmentedControl
的大小。
如果您也遇到这个问题,请考虑使用下面的代码。
func *(lhs: CGSize, rhs: CGFloat) -> CGSize {
return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
}
extension UIImage {
func resized(_ size: CGSize) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
self.draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
func resized(_ size: CGFloat) -> UIImage? {
guard size > 0, self.size.width > 0, self.size.height > 0 else { return nil }
let ratio = size / max(self.size.width, self.size.height)
return self.resized(self.size * ratio)
}
func refilled(_ color: UIColor) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color.set()
UIGraphicsGetCurrentContext()?.fill(CGRect(origin: .zero, size: self.size))
return UIGraphicsGetImageFromCurrentImageContext()
}
public convenience init?(color: UIColor = .clear, size: CGSize) {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContext(size)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.setFillColor(color.cgColor);
context.fill(CGRect(origin: .zero, size: size));
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
extension UISegmentedControl {
func removeBorders() {
let image = UIImage(size: self.bounds.size)
self.setBackgroundImage(image, for: .normal, barMetrics: .default)
self.setBackgroundImage(image?.refilled(self.tintColor), for: .selected, barMetrics: .default)
self.setDividerImage(image?.resized(1), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
易于使用:
segmentedControl.removeBorders()
如何删除分段控件的外边框? 我已将分隔线图像设置为我想要的,但现在要跟随我的应用程序的模拟,我需要有一个没有外边框的分段控件。
您必须了解的是 backgroundColor
属性 不是有状态的。
因此你必须使用 setBackgroundImage(_:for:barMetrics:)
。
我们可以使用以下函数轻松删除边框和分隔线。
对于 Swift 3 & 4+:
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
对于Swift 2.2:
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(backgroundColor!), forState: .Normal, barMetrics: .Default)
setBackgroundImage(imageWithColor(tintColor!), forState: .Selected, barMetrics: .Default)
setDividerImage(imageWithColor(UIColor.clearColor()), forLeftSegmentState: .Normal, rightSegmentState: .Normal, barMetrics: .Default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image
}
}
调用上面的函数。
segmentedControl.removeBorders()
参考:Remove UISegmentedControl separators completely. (iphone)
感谢 https://whosebug.com/users/3921490/amagain 提供 Swift 3 版本。
这是 Sohil 答案的 swift 3 版本,可能会对其他人有所帮助。它确实帮助了我。 :)
extension UISegmentedControl {
func removeBorders() {
setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
如果要保存单元格之间的边框
extension UISegmentedControl {
func removeBorders() {
if let backgroundColor = backgroundColor, let backgroundImage = UIImage.imageWithSize(size: CGSize.one_one, color: backgroundColor){
setBackgroundImage(backgroundImage, for: .normal, barMetrics: .default)
}
if let tintColor = tintColor, let tintImage = UIImage.imageWithSize(size: CGSize.one_one, color: tintColor){
setBackgroundImage(tintImage, for: .selected, barMetrics: .default)
setDividerImage(tintImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
}
extension CGSize{
static var one_one: CGSize{
return CGSize(width: 1.0, height: 1.0)
}
}
extension UIImage{
static func imageWithSize(size : CGSize, color : UIColor = UIColor.white) -> UIImage? {
var image:UIImage? = nil
UIGraphicsBeginImageContext(size)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.addRect(CGRect(origin: CGPoint.zero, size: size));
context.drawPath(using: .fill)
image = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext()
return image
}
}
希望对大家有所帮助
Swift - 4
将 Segment 控件的 Background 颜色和 Tint 颜色设置为相同的颜色。 然后 "set titleTextAttributes" 你的 Segment control
segmentedControl.tintColor = UIColor.red
segmentedControl.backgroundColor = UIColor.red
let attributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
segmentedControl.setTitleTextAttributes(attributes, for: .normal)
segmentedControl.setTitleTextAttributes(attributes, for: .selected)
您可能有不想要圆角边框的用例,因为如果它嵌入在单元格中,您不想看到它。在这种情况下,将自动布局约束设置为 -2 并且边框将被隐藏,因为它会超出单元格边框。
如果您只需要文本段控制,请使用,
segmentControl.backgroundColor = .clear
segmentControl.tintColor = .clear
let attributes: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.white]
segmentControl.setTitleTextAttributes(attributes, for: .normal)
let selectedAttrib: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.red]
segmentControl.setTitleTextAttributes(hightLightedStateAttrib, for: .selected)
注意:我在谷歌上搜索了很长时间,这就是我发布在这里的原因。
来源:CodeMentor
- 已接受的答案适用于消除边框。
- 提到的解决方案here也适用于禁用分段控件。
然而,将两个解决方案放在一起,我无法在 disabled
状态下获得正确的 selected 段。
我想要的是在选择段并进行网络调用时,我想禁用分段控制。
结果是这样的:
想要的是:
setBackgroundImage(imageWithColor(color: imageWithColor(color: tintColor)), for: [.selected, .disabled], barMetrics: .default)
在选择&&禁用后段将具有正确的颜色。
Swift 5.x:
此解决方案仅删除外部边框并保留每个按钮上的圆角
extension UISegmentedControl {
func removeBorders(andBackground:Bool=false) {
setBackgroundImage(imageWithColor(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default)
setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
_ = self.subviews.compactMap {
if ([=10=].frame.width>0) {
[=10=].layer.cornerRadius = 8
[=10=].layer.borderColor = UIColor.clear.cgColor
[=10=].clipsToBounds = true
[=10=].layer.borderWidth = andBackground ? 1.0 : 0.0
[=10=].layer.borderColor = andBackground ? tintColor?.cgColor : UIColor.clear.cgColor
andBackground ? [=10=].layer.backgroundColor = UIColor.clear.cgColor : nil
}
}
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
用法:
mySegmentedControl.removeBorders()
但是如果不设置UIImage
大小,可能会影响UISegmentedControl
的大小。
如果您也遇到这个问题,请考虑使用下面的代码。
func *(lhs: CGSize, rhs: CGFloat) -> CGSize {
return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
}
extension UIImage {
func resized(_ size: CGSize) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
self.draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
func resized(_ size: CGFloat) -> UIImage? {
guard size > 0, self.size.width > 0, self.size.height > 0 else { return nil }
let ratio = size / max(self.size.width, self.size.height)
return self.resized(self.size * ratio)
}
func refilled(_ color: UIColor) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color.set()
UIGraphicsGetCurrentContext()?.fill(CGRect(origin: .zero, size: self.size))
return UIGraphicsGetImageFromCurrentImageContext()
}
public convenience init?(color: UIColor = .clear, size: CGSize) {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContext(size)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.setFillColor(color.cgColor);
context.fill(CGRect(origin: .zero, size: size));
guard let cgImage = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
}
extension UISegmentedControl {
func removeBorders() {
let image = UIImage(size: self.bounds.size)
self.setBackgroundImage(image, for: .normal, barMetrics: .default)
self.setBackgroundImage(image?.refilled(self.tintColor), for: .selected, barMetrics: .default)
self.setDividerImage(image?.resized(1), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
易于使用:
segmentedControl.removeBorders()