draw (_ rect :) 함수를 사용할 때 이상한 검은 색 모서리
Dec 07 2020
함수 UIBezierPath
내부에 코드를 넣으면 draw(_ rect:)
보기와 꼬리 주위에이 이상한 매우 얇은 검은 색 모서리가 생깁니다. 보기를 끌 때 (예 : 표시된보기 컨트롤러 내에서) 이러한가는 선도 깜박이기 시작합니다. 나는 그것이 이상한 렌더링 버그라고 생각합니다. 이 문제를 해결할 방법이 있는지 아는 사람이 있습니까?

class RenderingView: UIView {
lazy var backgroundView: UIView = {
let view = UIView()
view.layer.cornerRadius = 8
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var shadowView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var textLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Rendering Bug"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
backgroundColor = .clear
backgroundView.backgroundColor = .yellow
layer.borderWidth = 0
setupLayout()
}
private func setupLayout() {
[shadowView, backgroundView, textLabel].forEach(addSubview)
backgroundView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
backgroundView.topAnchor.constraint(equalTo: topAnchor).isActive = true
backgroundView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
shadowView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
shadowView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
shadowView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
shadowView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor).isActive = true
textLabel.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 10).isActive = true
textLabel.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor, constant: -10).isActive = true
textLabel.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 10).isActive = true
textLabel.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -10).isActive = true
}
override func draw(_ rect: CGRect) {
shapeBackground()
}
private func shapeBackground() {
let tailLayer = CAShapeLayer()
let bezierPath = UIBezierPath(roundedRect: CGRect(x: backgroundView.bounds.minX,
y: backgroundView.bounds.minY,
width: backgroundView.bounds.width,
height: backgroundView.bounds.height - 12),
cornerRadius: 8)
let shadowBezierPath = UIBezierPath(roundedRect: CGRect(x: backgroundView.bounds.minX + 5,
y: backgroundView.bounds.minY + 10,
width: backgroundView.bounds.width - 10,
height: backgroundView.bounds.height - 12 - 10),
cornerRadius: 8)
[bezierPath, shadowBezierPath].forEach {
$0.move(to: CGPoint(x: backgroundView.bounds.midX - 12, y: backgroundView.bounds.maxY - 12)) $0.addLine(to: CGPoint(x: backgroundView.bounds.midX, y: backgroundView.bounds.maxY))
$0.addLine(to: CGPoint(x: backgroundView.bounds.midX + 12, y: backgroundView.bounds.maxY - 12)) $0.fill()
$0.close()
}
tailLayer.path = bezierPath.cgPath
tailLayer.fillColor = UIColor.white.cgColor
shadowView.layer.shadowPath = shadowBezierPath.cgPath
shadowView.layer.cornerRadius = 8
backgroundView.layer.masksToBounds = true
backgroundView.layer.mask = tailLayer
}
}
편집 :addClip()
이 모서리를 제거하기 위해 베 지어 경로를 사용해야 했습니다.
답변
2 Eskils Dec 07 2020 at 23:44
이것이 당신이 겨냥한 것인지 확실하지 않지만, shapeBackground()
방법을 밖으로 옮기고 draw(_ rect:)
약간의 수정을 할 때 완벽하게 보입니다 .
내부 드로잉 루틴 중 일부를 수정 하고 제약 조건으로 만든 프레임에서 꼬리의 위치를 계산하기 shapeBackground()
위해 함수를로 이동했습니다 layoutSubviews()
. tailWidth
, &에 대한 몇 가지 변수도 추가했습니다 tailHeight
.
이렇게 :
class RenderingView: UIView {
lazy var backgroundView: UIView = {
let view = UIView()
view.layer.cornerRadius = 8
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var shadowView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var textLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "No Rendering Bug"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
backgroundColor = .clear
backgroundView.backgroundColor = .systemTeal
//backgroundView.frame.size = CGSize(width: 100, height: 100)
layer.borderWidth = 0
setupLayout()
}
private func setupLayout() {
[shadowView, backgroundView, textLabel].forEach(addSubview)
backgroundView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
backgroundView.topAnchor.constraint(equalTo: topAnchor).isActive = true
backgroundView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
shadowView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
shadowView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
shadowView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
shadowView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor).isActive = true
textLabel.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 10).isActive = true
textLabel.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor, constant: -10).isActive = true
textLabel.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 10).isActive = true
textLabel.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -10).isActive = true
}
override func didMoveToWindow() {
super.didMoveToWindow()
}
override func layoutSubviews() {
super.layoutSubviews()
shapeBackground(color: UIColor.systemTeal)
}
override func draw(_ rect: CGRect) {
super.draw(rect)
}
private func shapeBackground(color: UIColor) {
let tailLayer = CAShapeLayer()
tailLayer.name = "tailLayer"
let tailWidth: CGFloat = 16
let tailHeight: CGFloat = 10
let bezierPath = UIBezierPath()
let shadowBezierPath = UIBezierPath()
[bezierPath, shadowBezierPath].forEach {
$0.move(to: CGPoint(x: 0, y: 0)) $0.addLine(to: CGPoint(x: tailWidth / 2, y: tailHeight))
$0.addLine(to: CGPoint(x: tailWidth, y: 0)) $0.fill()
$0.close()
}
tailLayer.path = bezierPath.cgPath
tailLayer.fillColor = color.cgColor
shadowView.layer.shadowPath = shadowBezierPath.cgPath
shadowView.layer.cornerRadius = 8
print(backgroundView.bounds.width)
tailLayer.frame = CGRect(x: (backgroundView.bounds.width - tailWidth) / 2,
y: backgroundView.bounds.maxY,
width: tailWidth,
height: tailHeight)
backgroundView.layer.masksToBounds = false
backgroundView.layer.addSublayer(tailLayer)
}
}