Цвет заливки не работает с помощью CAShapeLayer в Swift - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь изобразить приведенный ниже код для рисования фигуры, и это нормально, но Цвет фона UIView не отображается с тех пор, как я присвоил оранжевый цвет

См. Мой код:

let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
myView.backgroundColor = .orange
let circlePath = UIBezierPath(arcCenter: CGPoint(x: myView.bounds.size.width / 2, y: 0), radius: myView.bounds.size.height, startAngle: 0.0, endAngle: .pi, clockwise: false)
let circleShape = CAShapeLayer()
circleShape.masksToBounds = false
circleShape.path = circlePath.cgPath
circleShape.fillColor = UIColor.orange.cgColor
circleShape.strokeColor = UIColor.orange.cgColor
myView.layer.mask = circleShape
print(myView)

Выход на игровую площадку:

screen shot

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Попробуйте этот код:

    let myView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    myView.backgroundColor = .orange
    let circlePath = UIBezierPath(arcCenter: myView.center,
                                  radius: myView.bounds.size.width / 2,
                                  startAngle: 0.0,
                                  endAngle: .pi,
                                  clockwise: false)
    let circleShape = CAShapeLayer()
    circleShape.path = circlePath.cgPath
    myView.layer.mask = circleShape

Я думаю, вы не видите ожидаемого результата из-за неправильного arcCenter или начального и конечного ангелов

результат кода: enter image description here

0 голосов
/ 13 февраля 2020

Несколько замечаний:

  1. Вы просто смотрите на визуальное представление пути, а не на представление. Чтобы увидеть вид, вы должны установить liveView из PlaygroundPage:

    import PlaygroundSupport
    

    и

    PlaygroundPage.current.liveView = myView
    PlaygroundPage.current.needsIndefiniteExecution = true
    
  2. В стороне, ваш круговой вид идет от 0 до π против часовой стрелки. Т.е. это верхняя половина круга. Таким образом, если центр круга имеет y из 0, это означает, что ваш путь находится выше вида и не перекрывается с ним. Либо установите его на go по часовой стрелке (чтобы получить нижнюю половину круга), либо сдвиньте y вниз (чтобы верхняя половина круга перекрывала вид).

  3. Я обнаружил, что игровые площадки меняют свои liveView (даже если я установил wantsFullScreenLiveView на false), поэтому, если я хочу посмотреть определенный размер, я использую «вид контейнера». Т.е. я добавлю myView как подпредставление containerView, добавлю ограничения, чтобы поместить его в центр этого контейнера, а затем установлю containerView как liveView.

  4. Только по касательной, но вы устанавливаете цвет слоя формы маски оранжевым. Маски используют только свой альфа-канал, поэтому использование оранжевого не имеет смысла. Обычно мы устанавливаем маски на белый цвет, но я просто хотел убедиться, что мы не связываем цвет маски с цветом маскированного изображения.

Итак, потянув что все вместе:

import UIKit
import PlaygroundSupport

// create container
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false

// create view that we'll mask with shape layer
let rect = CGRect(x: 0, y: 0, width: 200, height: 200)
let myView = UIView()
myView.translatesAutoresizingMaskIntoConstraints = false
myView.backgroundColor = .orange
myView.clipsToBounds = true
containerView.addSubview(myView)

// create mask
let circlePath = UIBezierPath(arcCenter: CGPoint(x: rect.midX, y: rect.minY), radius: rect.height, startAngle: 0, endAngle: .pi, clockwise: true)
let circleShape = CAShapeLayer()
circleShape.masksToBounds = false
circleShape.path = circlePath.cgPath
circleShape.fillColor = UIColor.white.cgColor
circleShape.strokeColor = UIColor.white.cgColor
myView.layer.mask = circleShape

// center masked view in container
NSLayoutConstraint.activate([
    myView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
    myView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
    myView.widthAnchor.constraint(equalToConstant: 200),
    myView.heightAnchor.constraint(equalToConstant: 200)
])

// show it
PlaygroundPage.current.liveView = containerView
PlaygroundPage.current.needsIndefiniteExecution = true

Это дает:

enter image description here

Итак, сделав ar c go по часовой стрелке и теперь, используя liveView, мы можем это увидеть. Очевидно, что ar c, центр которого находится в midX, minY и имеет радиус height, не может показать полный полукруг. Вам нужно было бы установить радиус на width / 2 (или увеличить width на rect или что-то еще), если вы хотите увидеть полный полукруг.

0 голосов
/ 13 февраля 2020

Похоже, проблема связана с вашим circlePath, который имеет:

1) Неправильный центр дуги (CGPoint's y не центрирован) *

2) Радиус (должен быть наполовину высота / ширина вида, учитывая height = width и вам нужен круг)

3) Угол (должно быть 360 градусов)

Замените его определение на:

let circlePath = UIBezierPath(arcCenter: myView.center, radius: myView.bounds.height/2, startAngle: 0.0, endAngle: .pi * 2, clockwise: false)

и он должен работать как положено ...

все в порядке, но цвет фона UIView не отображается, так как я дал оранжевый цвет для просмотра

путь, который вы выбрали used даже не отображает слой, поскольку вы указали, что его угловой радиус такой же, как и его высота, и вы применили созданный предположительно невидимый слой в качестве маски вашего вида.

...