CALayer: добавить рамку только с одной стороны - PullRequest
62 голосов
/ 11 августа 2011

Я могу добавить границу для CALayer следующим образом:

[webView.layer setBorderColor: [[UIColor colorWithRed:0.6 green:0.7 blue:0.2 alpha:1] CGColor]];
[webView.layer setBorderWidth: 2.75];   

Но возможно ли добавить границу только с одной стороны?Мне нужна только граница внизу.Или я могу достичь этого с другими свойствами, например, рамка, границы, маска, ...?

enter image description here

Спасибо за вашу помощь!


@Control-V

        UIWebView *webView = [[UIWebView alloc] init];
        CALayer *webViewLayer = webView.layer;

        // now you can do a lot of stuff like borders:
        [webViewLayer setBorderColor: [[UIColor greenColor] CGColor]];
        [webViewLayer setBorderWidth: 2.75];    

Посмотрите документацию CALayer: https://developer.apple.com/documentation/quartzcore/calayer

И посмотрите здесь: http://iosdevelopertips.com/cocoa/add-rounded-corners-and-border-to-uiwebview.html

Ответы [ 7 ]

131 голосов
/ 20 декабря 2011

Я сделал правильную границу, используя это:

leftScrollView.clipsToBounds = YES;

CALayer *rightBorder = [CALayer layer];
rightBorder.borderColor = [UIColor darkGrayColor].CGColor;
rightBorder.borderWidth = 1;
rightBorder.frame = CGRectMake(-1, -1, CGRectGetWidth(leftScrollView.frame), CGRectGetHeight(leftScrollView.frame)+2);

[leftScrollView.layer addSublayer:rightBorder];
17 голосов
/ 06 марта 2012

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

Я реализовал решение с открытым исходным кодом, которое позаботится об этих проблемах, и позволит вам объявить выборочные границы следующим образом:

myView.borderDirection = AUIFlexibleBordersDirectionRight | AUIFlexibleBordersDirectionTop;

Вы можете получить код и прочитать о нем еще здесь

7 голосов
/ 11 августа 2011

Свойство border всегда добавляет границу к 4 сторонам вашего вида.Вы можете создать свой собственный метод рисования, чтобы нарисовать границу в нижней части вашего представления.

Но почему бы вам просто не добавить представление над UIWebView, чтобы оно выглядело как граница?

6 голосов
/ 24 января 2017

My Swift Solution. Он включает в себя четыре разные функции, все расширения UIView. Каждая функция добавляет свою границу.

extension UIView {
@discardableResult func addRightBorder(color: UIColor, width: CGFloat) -> UIView {
    let layer = CALayer()
    layer.borderColor = color.cgColor
    layer.borderWidth = width
    layer.frame = CGRect(x: self.frame.size.width-width, y: 0, width: width, height: self.frame.size.height)
    self.layer.addSublayer(layer)
    return self
    }
@discardableResult func addLeftBorder(color: UIColor, width: CGFloat) -> UIView {
    let layer = CALayer()
    layer.borderColor = color.cgColor
    layer.borderWidth = width
    layer.frame = CGRect(x: 0, y: 0, width: width, height: self.frame.size.height)
    self.layer.addSublayer(layer)
    return self
    }
@discardableResult func addTopBorder(color: UIColor, width: CGFloat) -> UIView {
    let layer = CALayer()
    layer.borderColor = color.cgColor
    layer.borderWidth = width
    layer.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: width)
    self.layer.addSublayer(layer)
    return self
    }
@discardableResult func addBottomBorder(color: UIColor, width: CGFloat) -> UIView {
    let layer = CALayer()
    layer.borderColor = color.cgColor
    layer.borderWidth = width
    layer.frame = CGRect(x: 0, y: self.frame.size.height-width, width: self.frame.size.width, height: width)
    self.layer.addSublayer(layer)
    return self
    }
}
5 голосов
/ 20 июля 2015

Вот быстрый эквивалент

leftScrollView.clipsToBounds = true
let rightBorder: CALayer = CALayer()
rightBorder.borderColor = UIColor.darkGrayColor().CGColor
rightBorder.borderWidth = 1
rightBorder.frame = CGRectMake(-1, -1, CGRectGetWidth(leftScrollView.frame), CGRectGetHeight(leftScrollView.frame)+2)
leftScrollView.layer.addSublayer(rightBorder)
2 голосов
/ 04 мая 2016

Есть еще один способ сделать это.CAShapeLayer имеет свойства, называемые "strokeStart" и "strokeEnd".Учитывая, что обводка начинается с 0 и заканчивается на 1, когда она достигает начала координат, завершая путь, вы можете установить значения для начала и конца, чтобы нарисовать границу на одной стороне.

Относительное расположениес чего начать поглаживать путь.Animatable.Значение этого свойства должно быть в диапазоне от 0,0 до 1,0.Значение по умолчанию этого свойства - 0.0.В сочетании со свойством strokeEnd это свойство определяет субрегион пути к штриху.Значение в этом свойстве указывает относительную точку вдоль пути, с которой начинается штрихование, а свойство strokeEnd определяет конечную точку.Значение 0,0 представляет начало пути, а значение 1,0 представляет конец пути.Значения между ними интерпретируются линейно по длине пути.

Пример:

let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.CGPath
mask.strokeColor = UIColor.redColor().CGColor
mask.strokeStart = 0.45
mask.strokeEnd = 0.92
self.layer.mask = mask
0 голосов
/ 29 января 2019

Следующее работает со Swift 4.2 для применения границы вдоль существующего UIView.

extension UIView {
    enum Side {
        case top
        case bottom
        case left
        case right
    }

    func addBorder(to side: Side, color: UIColor, borderWidth: CGFloat) {
        let subLayer = CALayer()
        subLayer.borderColor = color.cgColor
        subLayer.borderWidth = borderWidth
        let origin = findOrigin(side: side, borderWidth: borderWidth)
        let size = findSize(side: side, borderWidth: borderWidth)
        subLayer.frame = CGRect(origin: origin, size: size)
        layer.addSublayer(subLayer)
    }

    private func findOrigin(side: Side, borderWidth: CGFloat) -> CGPoint {
        switch side {
        case .right:
            return CGPoint(x: frame.maxX - borderWidth, y: 0)
        case .bottom:
            return CGPoint(x: 0, y: frame.maxY - borderWidth)
        default:
            return .zero
        }
    }

    private func findSize(side: Side, borderWidth: CGFloat) -> CGSize {
        switch side {
        case .left, .right:
            return CGSize(width: borderWidth, height: frame.size.height)
        case .top, .bottom:
            return CGSize(width: frame.size.width, height: borderWidth)
        }
    }
}

И вы можете назвать это так:

myView.addBorder(to: .left, color: .black, borderWidth: 2.0)

Что происходитon:

  • Пользователь предоставляет Side, как определено в перечислении, наряду с color и borderWidth
  • Создается и передается новый подслойa borderColor и borderWidth
  • Исходное значение рассчитывается по определению стороны
  • Размер рассчитывается также по определению стороны
  • Наконец,слой получает кадр, а затем добавляется в качестве подслоя
...