Измените стиль endcap .round, чтобы он был более округлым, в отличие от показанного здесь примера изображения. - PullRequest
0 голосов
/ 02 октября 2019

Я только что узнал, что стандарт Apple .round торцевая крышка

let l = CAShapeLayer()
l.path = .. just a straight line, say 50 long
l.lineWidth =  say "3.1" in the example shown here
l.lineCap = .round

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

Если мне нужны, по-видимому, "точные полукруглые" концевые колпачки, что делать?

Я ценю, что могу построить свою собственную линию линии и заполнить ее.

Но есть лиспособ, возможно, подкласс "endcap" каким-то образом?

Было бы волшебным, если бы вы могли сказать = .myHappyEndcapMode

enter image description here

Как это исправить?

enter image description here

enter image description here

enter image description here

Вы можете увидеть, как далеко это здесь:

enter image description here

Дополнительная информация:

Некруглый визуальный вид возникает в случае:

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

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Мне интересно, видите ли вы что-то, чего нет у нас ...

Вот конец строки, ширина 8 пт (которая отображается в 16 пикселях на iPhone 8), увеличеннаядо 3200%

enter image description here

Как видите, закругленная торцевая крышка имеет радиус точно 8 пикселей.

А вот фактическая крышка экрана, которую я использовал, чтобы получить увеличенное изображение выше. Ширина линий варьируется от 1 до 10:

enter image description here


РЕДАКТИРОВАТЬ

Хммм .. Кажется, что либо A) Он оптический, и вы не учитываете все сглаженные пиксели в ваших увеличенных изображениях (то есть, когда заглушка равна , онапросто не выглядит вокруг вас) или B) Может быть, вы масштабируете / растягиваете свое изображение / слои?

Вот еще пара примеров изображений- на этот раз я использую CAShapeLayer в качестве маски для CAGradientLayer, наложенного на UIImageView:

enter image description here

enter image description here

Крышка экрана, используемая для увеличенных изображений:

enter image description here

И источник для создания этого представления,если вы хотите поиграть с ним:

class GradientView: UIView {

    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }

    lazy var gradientLayer: CAGradientLayer = {
        return self.layer as! CAGradientLayer
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {

        if let l = layer as? CAGradientLayer {
            let c1 = UIColor(rgb: 0x6119D2)
            let c2 = UIColor(rgb: 0x7E1CC6)

            l.colors = [c1.cgColor, c2.cgColor]
            l.startPoint = CGPoint(x: 0.0, y: 0.0)
            l.endPoint = CGPoint(x: 1.0, y: 0.0)
        }

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let l = CAShapeLayer()
        let bez = UIBezierPath()
        let xOffset = bounds.size.height * 0.5 + 4
        bez.move(to: CGPoint(x: xOffset, y: bounds.size.height * 0.5))
        bez.addLine(to: CGPoint(x: bounds.size.width - xOffset, y: bounds.size.height * 0.5))
        l.lineCap = .round
        l.lineWidth = bounds.size.height
        l.strokeColor = UIColor.black.cgColor
        l.path = bez.cgPath

        self.layer.mask = l

    }
}

class EndCapViewController: UIViewController {

    let gView: GradientView = {
        let v = GradientView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let imgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .scaleAspectFit
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        if let img = UIImage(named: "clouds") {
            imgView.image = img
        }

        view.addSubview(imgView)
        view.addSubview(gView)

        let lineThickness: CGFloat = 8.0

        NSLayoutConstraint.activate([

            imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            imgView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            imgView.widthAnchor.constraint(equalToConstant: 128.0),
            imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: 1.0),

            gView.widthAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: 1.0),
            gView.heightAnchor.constraint(equalToConstant: lineThickness),
            gView.centerXAnchor.constraint(equalTo: imgView.centerXAnchor),
            gView.centerYAnchor.constraint(equalTo: imgView.centerYAnchor),

        ])

    }

}

extension UIColor {
    convenience init(red: Int, green: Int, blue: Int) {
        assert(red >= 0 && red <= 255, "Invalid red component")
        assert(green >= 0 && green <= 255, "Invalid green component")
        assert(blue >= 0 && blue <= 255, "Invalid blue component")

        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }

    convenience init(rgb: Int) {
        self.init(
            red: (rgb >> 16) & 0xFF,
            green: (rgb >> 8) & 0xFF,
            blue: rgb & 0xFF
        )
    }
}
1 голос
/ 03 октября 2019

Нет способа «подкласса» формы шапки. Вам нужно будет вручную создать контур формы, если вы хотите использовать другую форму колпачка.

Круглая крышка уже точно такая же круглая, как и круг, созданный с помощью CGPath(ellipseIn:).

Вотлиния с закругленными углами, нарисованная на вершине круга немного большего радиуса, увеличенная в 8 раз:

zoomed image

Кривизна линейного колпачка начинается точно на горизонтальнойцентр круга.

Вот код:

import UIKit
import PlaygroundSupport

let lineWidth: CGFloat = 20
let circleRadius = lineWidth / 2 + 1

let lineLayer = CAShapeLayer()
lineLayer.position = .init(x: 30, y: 30)
let path = CGMutablePath()
path.move(to: .zero)
path.addLine(to: .init(x: 30, y: 0))
lineLayer.path = path
lineLayer.lineWidth = lineWidth
lineLayer.lineCap = .round
lineLayer.strokeColor = UIColor.gray.cgColor
lineLayer.fillColor = nil

let circleLayer = CAShapeLayer()
circleLayer.position = lineLayer.position
circleLayer.path = CGPath(ellipseIn: CGRect.zero.insetBy(dx: -circleRadius, dy: -circleRadius), transform: nil)
circleLayer.fillColor = UIColor.blue.cgColor

let view = UIView(frame: .init(x: 0, y: 0, width: 100, height: 80))
view.layer.backgroundColor = UIColor.white.cgColor
view.layer.addSublayer(circleLayer)
view.layer.addSublayer(lineLayer)
PlaygroundPage.current.liveView = view
...