gpt4 book ai didi

ios - 子层未按预期隐藏/显示

转载 作者:行者123 更新时间:2023-11-30 11:51:19 26 4
gpt4 key购买 nike

我有一个自定义按钮,其中包含一些在 draw(_ rect: CGRect) 中添加的 CAShapeLayer。我希望在 recordingtrue 时隐藏 circleLayer;但是,仅当 recording 设置为 false 后,circleLayer 才会隐藏。

我注意到的一些其他症状:

  1. circleLayer 第一次正确隐藏/显示(当 View 首次加载时)
  2. 如果我呈现模态视图 Controller 然后关闭模态视图 Controller ,此行为会自行纠正。

由于如果呈现模态视图 Controller 然后将其关闭,此问题会自行纠正,因此我相信这只是 View 未正确重绘自身的问题。但是,我似乎无法修复它。

如有任何帮助,我们将不胜感激。

class RecordButton: TouchAnimationButton {

var recording: Bool = false {
didSet {
self.setNeedsDisplay()
}
}

private static let ringLayerLineWidthRatio: CGFloat = 0.1
private static let separatorWidthRatio: CGFloat = 0.2
private static let squareLayerCornerRadiusRatio: CGFloat = 0.1

lazy var ringLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = UIBezierPath().cgPath
layer.speed = 0.0
layer.strokeColor = UIColor.white.cgColor
layer.fillColor = UIColor.clear.cgColor
return layer
}()

lazy var circleLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = UIBezierPath().cgPath
layer.speed = 0.0
layer.fillColor = UIColor.red.cgColor
layer.strokeColor = UIColor.clear.cgColor
layer.lineWidth = 0.0
return layer
}()

lazy var squarePath: CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = UIBezierPath().cgPath
layer.speed = 0.0
layer.fillColor = UIColor.red.cgColor
layer.strokeColor = UIColor.clear.cgColor
layer.lineWidth = 0.0
return layer
}()

func getCirclePath() -> UIBezierPath {
let radius = (getMinDim() - getRingLayerLineWidth() - getSeparatorWidth()) / 2.0
let center = CGPoint(x: self.bounds.size.width / 2.0, y: self.bounds.size.height / 2.0)

let path = UIBezierPath()
path.addArc(withCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
return path
}

func getRingPath() -> UIBezierPath {
let center = CGPoint(x: self.bounds.size.width / 2.0, y: self.bounds.size.height / 2.0)
let radius = (getMinDim() - getRingLayerLineWidth()) / 2.0

let path = UIBezierPath()
path.addArc(withCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
return path
}

func getSquarePath() -> UIBezierPath {
let radius = (getMinDim() - getRingLayerLineWidth() - 1.5 * getSeparatorWidth()) / 2.0
let center = CGPoint(x: self.bounds.size.width / 2.0, y: self.bounds.size.height / 2.0)
let cornerRadius = RecordButton.squareLayerCornerRadiusRatio * getMinDim()
let side = sqrt(2) * radius
let halfSide = side / 2.0

let path = UIBezierPath()
path.move(to: CGPoint(x: center.x - halfSide + cornerRadius , y: center.y - halfSide))
path.addLine(to: CGPoint(x: center.x + halfSide - cornerRadius, y: center.y - halfSide))
path.addArc(withCenter: CGPoint(x: center.x + halfSide - cornerRadius, y: center.y - halfSide + cornerRadius),
radius: cornerRadius,
startAngle: CGFloat(3.0 * Double.pi / 2.0),
endAngle: CGFloat(2.0 * Double.pi),
clockwise: true)
path.addLine(to: CGPoint(x: center.x + halfSide, y: center.y + halfSide - cornerRadius))
path.addArc(withCenter: CGPoint(x: center.x + halfSide - cornerRadius, y: center.y + halfSide - cornerRadius),
radius: cornerRadius,
startAngle: CGFloat(0),
endAngle: CGFloat(Double.pi / 2.0),
clockwise: true)
path.addLine(to: CGPoint(x: center.x - halfSide + cornerRadius, y: center.y + halfSide))
path.addArc(withCenter: CGPoint(x: center.x - halfSide + cornerRadius, y: center.y + halfSide - cornerRadius),
radius: cornerRadius,
startAngle: CGFloat(Double.pi / 2.0),
endAngle: CGFloat(Double.pi),
clockwise: true)
path.addLine(to: CGPoint(x: center.x - halfSide, y: center.y - halfSide + cornerRadius))
path.addArc(withCenter: CGPoint(x: center.x - halfSide + cornerRadius, y: center.y - halfSide + cornerRadius),
radius: cornerRadius,
startAngle: CGFloat(Double.pi),
endAngle: CGFloat(3.0 * Double.pi / 2.0),
clockwise: true)
return path
}

func getMinDim() -> CGFloat {
return min(self.bounds.size.width, self.bounds.size.height)
}

func getRingLayerLineWidth() -> CGFloat {
return RecordButton.ringLayerLineWidthRatio * getMinDim()
}

func getSeparatorWidth() -> CGFloat {
return RecordButton.separatorWidthRatio * getMinDim()
}

override func draw(_ rect: CGRect) {
super.draw(rect)

if self.squarePath.superlayer == nil {
self.layer.addSublayer(self.squarePath)
}

if self.circleLayer.superlayer == nil {
self.layer.addSublayer(self.circleLayer)
}

if self.ringLayer.superlayer == nil {
self.layer.addSublayer(self.ringLayer)
}

self.ringLayer.lineWidth = getRingLayerLineWidth()

self.ringLayer.path = self.getRingPath().cgPath
self.circleLayer.path = self.getCirclePath().cgPath
self.squarePath.path = self.getSquarePath().cgPath

self.circleLayer.isHidden = self.recording
}
}

class TouchAnimationButton: UIButton {

private static let transformAnimationTime = 0.15

private var initialTransform: CGAffineTransform? = nil

override func layoutSubviews() {
super.layoutSubviews()

self.layer.minificationFilter = kCAFilterTrilinear
if initialTransform == nil {
initialTransform = self.layer.affineTransform()
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
weak var weakSelf = self
UIView.animate(withDuration: TouchAnimationButton.transformAnimationTime, animations: {
guard let view = weakSelf, let initialTransform = view.initialTransform else {
return
}
view.layer.setAffineTransform(initialTransform.scaledBy(x: 0.9, y: 0.9))
})
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)

weak var weakSelf = self
if let point = touches.first?.location(in: self),
self.bounds.contains(point) {
weak var weakSelf = self
self.layer.shouldRasterize = true
UIView.animate(withDuration: TouchAnimationButton.transformAnimationTime, animations: {
guard let view = weakSelf, let initialTransform = view.initialTransform else {
return
}
view.layer.setAffineTransform(initialTransform.scaledBy(x: 0.9, y: 0.9))
})
} else {
UIView.animate(withDuration: TouchAnimationButton.transformAnimationTime, animations: {
guard let view = weakSelf, let initialTransform = view.initialTransform else {
return
}
view.layer.setAffineTransform(initialTransform)
}, completion: { finished in
weakSelf?.contentScaleFactor = UIScreen.main.scale
})
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
weak var weakSelf = self
UIView.animate(withDuration: TouchAnimationButton.transformAnimationTime, animations: {
guard let view = weakSelf, let initialTransform = view.initialTransform else {
return
}
view.layer.setAffineTransform(initialTransform)
}, completion: { finished in
weakSelf?.contentScaleFactor = UIScreen.main.scale
})
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
weak var weakSelf = self
UIView.animate(withDuration: TouchAnimationButton.transformAnimationTime, animations: {
guard let view = weakSelf, let initialTransform = view.initialTransform else {
return
}
view.layer.setAffineTransform(initialTransform)
}, completion: { finished in
weakSelf?.contentScaleFactor = UIScreen.main.scale
})
}
}

最佳答案

这里我在我的baseView上添加了一个CAShapeLayer:

//My Bezier path
let combined = UIBezierPath()

//Create A layer instance
let maskLayer = CAShapeLayer()

//Setting Bounds
maskLayer.frame = baseView.bounds

//Assign a Name to layer that you will add
//This is important as if you want to remove a layer added by you
maskLayer.name = "tailView"

//Assigned my path
maskLayer.path = combined.cgPath

调用此函数删除CAShapeLayer

func removeLayerFromView(baseView: UIView)
{
if let layer = baseView.layer.mask?.name
{
//Check Layer name
if layer == "tailView"
{
//if yes Remove it
baseView.layer.mask?.removeFromSuperlayer()
}
else
{
//Layer not found
print("Layer not found")
}

}
}

在 UIView 中删除图层的行

//self.secondMainView name of View from which layer to be Removed
self.removeLayerFromView(baseView: self.secondMainView)

当您对 View 进行子类化时,如果 View 未更新,请调用 SetNeedsDisplay

关于ios - 子层未按预期隐藏/显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48294371/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com