【发布时间】:2015-10-17 13:45:21
【问题描述】:
如何删除分段控件的外边框? 我已将分隔线图像设置为我想要的,但现在要遵循我的应用程序的模拟,我需要有一个没有外边框的分段控件。
【问题讨论】:
标签: ios swift uisegmentedcontrol
如何删除分段控件的外边框? 我已将分隔线图像设置为我想要的,但现在要遵循我的应用程序的模拟,我需要有一个没有外边框的分段控件。
【问题讨论】:
标签: ios swift uisegmentedcontrol
Sohil's answer 确实帮助了我。
但是如果不设置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://stackoverflow.com/users/3921490/amagain Swift 3 版本。
【讨论】:
fatal error: unexpectedly found nil while unwrapping an Optional value在线setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default)
Default 以外的其他颜色。 backgroundColor 设置为 Default 时为 nil。
setBackgroundImage(imageWithColor(color: backgroundColor ?? .white), for: .normal, barMetrics: .default)
此解决方案仅删除外部边框并保留每个按钮上的圆角
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 ($0.frame.width>0) {
$0.layer.cornerRadius = 8
$0.layer.borderColor = UIColor.clear.cgColor
$0.clipsToBounds = true
$0.layer.borderWidth = andBackground ? 1.0 : 0.0
$0.layer.borderColor = andBackground ? tintColor?.cgColor : UIColor.clear.cgColor
andBackground ? $0.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()
【讨论】:
然而,将这两个解决方案放在一起,我无法在disabled 状态下获得正确的selected 段。
我想要的是在选择一个段并进行网络调用时,我想禁用分段控件。
结果是这样的:
想要的是这样的:
Sohil's solution 的唯一补充是:
setBackgroundImage(imageWithColor(color: imageWithColor(color: tintColor)), for: [.selected, .disabled], barMetrics: .default)
在选中&&禁用段之后会有正确的颜色。
【讨论】:
如果您只需要对文本进行分段控制,请使用,
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
【讨论】:
您可能有不想要圆形边框的用例,因为如果它嵌入在单元格中,您不想看到它。在这种情况下,将自动布局约束设置为 -2,边框将被隐藏,因为它将超出单元格边框。
【讨论】:
希望对大家有所帮助
斯威夫特 - 4
将 Segment 控件的背景颜色和色调颜色设置为相同的颜色。 然后“设置段控件的 titleTextAttributes”
segmentedControl.tintColor = UIColor.red
segmentedControl.backgroundColor = UIColor.red
let attributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
segmentedControl.setTitleTextAttributes(attributes, for: .normal)
segmentedControl.setTitleTextAttributes(attributes, for: .selected)
【讨论】:
如果你想保存单元格之间的边框
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
}
}
【讨论】:
这是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!
}
}
【讨论】: