The project uses ASDK (Texture). There is a main node, it has a subnode, under certain circumstances it is necessary to show the outer boundary of the subnode, in this project it is done by adding a border node and UIGraphicsGetCurrentContext
, also the task is to border line width be the same on all devices regardless of UIScreen.main.scale
. I did a test code and everything works fine, except that the lower and upper lines have a smaller width than the side lines (which are displayed correctly). Please tell how to fix it? I can not spread the screenshoot of the whole screen, but I uploaded the part so I can show what the problem is. You can see the green color on the bottom line, this should not be.
private func enableEditingMode() {
let solidBorderStyle = BorderStyle.solid
let border = ASBorderNode(shapeType: self.shapeType, borderType: solidBorderStyle)
border.frame = ASBorderNode.calculateFrame(self.shapeType, borderType: solidBorderStyle, superView: frame)
supernode?.insertSubnode(border, at: 0)
}
enum BorderStyle {
case dashed
case solid
case solidLight
var lineWidth: CGFloat {
switch self {
case .dashed:
return 1
case .solid:
return 6 / UIScreen.main.scale
case .solidLight:
return 2
}
}
}
class ASBorderNode: ASDisplayNode {
private (set) var shapeType: TemplateLayoutElement.Shape?
private (set) var borderType: BorderStyle
init(shapeType:TemplateLayoutElement.Shape?, borderType:BorderStyle = .dashed) {
self.borderType = borderType
self.shapeType = shapeType
super.init()
self.isOpaque = false
}
class func calculateFrame(_ shapeType: TemplateLayoutElement.Shape?, borderType: BorderStyle, superView frame: CGRect) -> CGRect {
switch borderType {
case .solid:
let lineWidth = borderType.lineWidth //* UIScreen.main.scale
let widthHeightValue = lineWidth * 2
return CGRect(x: -lineWidth + frame.origin.x, y: -lineWidth + frame.origin.y, width: frame.width + widthHeightValue, height: frame.height + widthHeightValue)
default:
assertionFailure("Implement for specific style")
return .zero
}
}
override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled isCancelledBlock: () -> Bool, isRasterizing: Bool) {
if let context = UIGraphicsGetCurrentContext(),
let parameters = parameters as? ASBorderNode {
switch parameters.borderType {
case .dashed:
break
case .solid:
context.setStrokeColor(UIColor.black.withAlphaComponent(0.5).cgColor)
context.setFillColor(UIColor.clear.cgColor)
context.setLineWidth(parameters.borderType.lineWidth)
case .solidLight:
break
}
switch parameters.shapeType {
case .circle?:
break
default:
switch parameters.borderType {
case .solid:
debugPrint("Bounds", bounds)
let frame = bounds.insetBy(dx: parameters.borderType.lineWidth / UIScreen.main.scale, dy: parameters.borderType.lineWidth / UIScreen.main.scale)
debugPrint("insetBy", frame)
context.addRect(frame)
default:
break
}
}
context.strokePath()
}
}
override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
return self
}
}
I believe what you're seeing is a stroke artifact. The only way I know how to avoid them is to build a path that corresponds to what you want the stroke shape to be and use fill
(so you're layering filled objects on top of each other, rather than just stroking the base path).