Как убрать границу из сегментированного контроля

Как удалить внешнюю границу сегментированного элемента управления? Я установил изображение делителя на то, что хотел, но теперь, чтобы следовать макету моего приложения, мне нужно иметь сегментированный элемент управления без внешней границы.

Ответ 1

То, что вы должны понимать, это свойство backgroundColor не с состоянием. Следовательно, вы должны использовать setBackgroundImage(_:for:barMetrics:).

Мы можем легко удалить как границы, так и разделители, используя функцию ниже.

Для 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()

Ссылка: Полностью удалите разделители UISegmentedControl. (iphone)

Благодаря https://stackoverflow.com/users/3921490/amagain для версии Swift 3.

Ответ 2

Здесь приведена быстрая версия 3 Sohil, которая может помочь кому-то другому. Это помогло мне.:)

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

Ответ 3

Надеюсь, это поможет кому-то

Свифт - 4

Сделайте цвет фона и оттенок вашего элемента управления Сегмент одинаковыми. Затем "установить 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)

Ответ 4

Если вы хотите сохранить границы между ячейками

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

Ответ 5

Swift 5.x:

Это решение удаляет только внешнюю границу и сохраняет закругленный angular на каждой кнопке

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

Ответ 6

Возможно, у вас есть сценарий использования, в котором вы не хотите, чтобы закругленная граница не отображалась, если она встроена в ячейку. В этом случае установите для ограничений автоматического размещения значение -2, и граница будет скрыта, поскольку она будет выходить за границы ячейки.

Ответ 7

Если вам нужен сегментный контроль только с текстами, используйте,

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: Я гуглил это долгое время, поэтому я размещен здесь.

Источник: CodeMentor

Ответ 8

  • Принятый ответ работает для избавления от границы.
  • Упомянутое здесь решение также работает для отключения сегментированного элемента управления.

Однако, объединив два решения, я не смог получить правильный выбранный сегмент в disabled состоянии.

Я хотел, чтобы при выборе сегмента и выполнении сетевого вызова я хотел отключить сегментированный элемент управления.

Результат был таким:

enter image description here

Что было желаемым, так это:

enter image description here

Единственным дополнением к решению Sohil является:

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

После того как выбранный && отключенный сегмент будет иметь правильный цвет.