Date
1 - 4 of 4
CGContext always creating a black rect.
On 24 Jul 2021, at 12:56 pm, Alex Zavatone via groups.io <zav@...> wrote:I initially felt that way too, several years ago, when first coming from Obj-C. However, I learned to embrace the tools (which make it easy to find the declaration) and also be mindful of writing clear and well-organized code to keep the mental burden of symbol bookkeeping to a minimum. Moreover, following conventional style (which, in Swift, eschews the redundant `self.`) makes it easier to work with other developers. Seems like your `configure(…)` method is the ideal place for those calculations.- That same function seems like it ought to be pure; i.e., have no side effects -- just draw a rect based on its argument. However, it does math and sets instance variables. If it needs to affect and act on persistent state, it ought to be refactored.Refactored how? [...] In Swift, I HATE how they have done method parameters, so I’m opting for redundant redundancy over terseness or brevity.I'm not sure what you're referring to about "how they have done method parameters". -ben |
|
Alex Zavatone
Thanks.
I know I don’t need the self, but I want the context. A variable just sitting around tells me nothing about the context in which it exists. I want to see the context and want to see the self. - The `roundRect(…)` function would be better named as `drawRoundRect(…)`. Good point.
Want them. They indicate scope. I don’t need to think. I just look at it and know the scope. Anything that makes code more vague sucks. I want easier understanding rather than “but we can use less words!” People’s time is $$.
It can’t exist without its configuration being set and it will be drawing with those internal settings once I have the details set up. Then it’s possible that I’ll move the configuration internal. Eventually, it will have a gradient interior. It’s replacing a UISwitch. Here’s how I currently call it. self.roundedRect = RoundedRectUIView() self.roundedRect.backgroundColor = .clear self.roundedRect.clipsToBounds = true let rectBorderWidth = CGFloat(2) let rectWidth = CGFloat(100) let rectHeight = CGFloat(40) let rectBorderColor = UIColor.blue let rectBgColor = UIColor.systemGray3 let rectCornerRadius = CGFloat(-1) let origin = CGPoint(x: 10, y: 200) viewRect = CGRect(origin: origin, size: CGSize(width: rectWidth + rectBorderWidth * 2.0, height: rectHeight + (rectBorderWidth * 2.0))) self.roundedRect.frame = viewRect self.roundedRect.configure(rectWidth: rectWidth, rectHeight: rectHeight, rectBgColor: rectBgColor , rectBorderColor: rectBorderColor, rectBorderWidth: rectBorderWidth, rectCornerRadius: rectCornerRadius) self.view.addSubview(roundedRect) In Swift, I HATE how they have done method parameters, so I’m opting for redundant redundancy over terseness or brevity. Thanks, Ben.
|
|
On 24 Jul 2021, at 11:37 am, Alex Zavatone via groups.io <zav@...> wrote:Move your `backgroundColor` and `isOpaque` calls to the init method(s). I set up a test project with your code, and that solves the problem. I was going to make that suggestion before I even tested it, though, because it's an obvious smell to me: there's no need to repeatedly set those properties every time you draw, but rather just once, at setup. A couple of other code style comments: - You don't need all the `self.` prefixes. - The `roundRect(…)` function would be better named as `drawRoundRect(…)`. - That same function seems like it ought to be pure; i.e., have no side effects -- just draw a rect based on its argument. However, it does math and sets instance variables. If it needs to affect and act on persistent state, it ought to be refactored. -ben |
|
Alex Zavatone
Hi. I’m trying to draw a bezier shape in CGContext on a UIView in Swift with a transparent background and the background is always black. Nothing online helps.
Any ideas? I’ve checked .isOpaque, backgroundColor. Nothing I can do to get rid of the black rect background. Any ideas? Thanks in advance. override func draw(_ rect: CGRect) { self.backgroundColor = .clear self.isOpaque = false super.draw(rect) roundRect(rect) } internal func roundRect(_ rect: CGRect) { self.backgroundColor = UIColor.clear // Make a pill shape if rectCornerRadius < 0 let xHalf = self.frame.width / 2 let yHalf = self.frame.height / 2 if (self.rectCornerRadius < 0) { if (self.rectWidth <= self.rectHeight) { self.rectCornerRadius = (yHalf / 2) } else if (self.rectHeight <= self.rectWidth) { self.rectCornerRadius = (xHalf / 2) } } let ctx: CGContext = UIGraphicsGetCurrentContext()! ctx.clear(rect) ctx.saveGState() ctx.setLineWidth(rectBorderWidth) ctx.setStrokeColor(rectBorderColor.cgColor) let rect = CGRect(x: 0, y: 0, width: self.rectWidth, height: self.rectHeight) let clipPath: CGPath = UIBezierPath(roundedRect: rect, cornerRadius: self.rectCornerRadius).cgPath let linePath: CGPath = UIBezierPath(roundedRect: rect, cornerRadius: self.rectCornerRadius).cgPath ctx.addPath(clipPath) ctx.setFillColor(self.rectBgColor.cgColor) ctx.closePath() ctx.fillPath() ctx.addPath(linePath) ctx.strokePath() ctx.restoreGState() } |
|