如何从分段控件

时间:2015-07-27 11:32:45

标签: ios swift uisegmentedcontrol

如何删除分段控件的外边框? 我已经将分频器图像设置为我想要的但现在要按照我的应用程序的模拟我需要一个没有外边框的分段控件。

9 个答案:

答案 0 :(得分:45)

您可以使用以下功能删除边框和分隔线。创建UISegmentedControl扩展:

  

对于Swift 3& 4 +:

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!
    }
}
  

对于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)

感谢Swift 3版本的https://stackoverflow.com/users/3921490/amagain

答案 1 :(得分:11)

这是Sohil的快速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!
    }
}

答案 2 :(得分:6)

希望它会帮助某人

斯威夫特 - 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)

答案 3 :(得分:2)

如果要在单元格之间保存边框

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
  }
}

答案 4 :(得分:0)

您可能有一个用例,您不想用圆角边框,因为您不想看到圆形边框(如果它嵌入在单元格中)。在这种情况下,将自动布局约束设置为-2,边框将隐藏,因为它将延伸到单元格边框之外。

答案 5 :(得分:0)

如果您需要仅包含文本的句段控制,请使用

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)

NB:我用Google搜索了很长时间,这就是为什么我在这里发布。

来源:CodeMentor

答案 6 :(得分:0)

  • 已接受的答案可以摆脱边界。
  • 提到的解决方案here也可用于禁用分段的控件。

尽管将这两个解决方案放在一起,但我无法在disabled状态下获得正确的选择段。

我想要的是在选择一个细分并进行网络通话后,我想禁用该细分控件。

结果是这样的:

enter image description here

所需的是:

enter image description here

Sohil's solution的唯一添加项是:

setBackgroundImage(imageWithColor(color: imageWithColor(color: tintColor)), for: [.selected, .disabled], barMetrics: .default)

已选择&&禁用的段之后,颜色将正确。

答案 7 :(得分:0)

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 ($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()

答案 8 :(得分:0)

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()