-1

I have the following code and have declared IBDesignable.

The DrawRect is shown perfectly well in Interface Builder, but not at all in the Simulator or on Device.

Does anybody have any ideas why?

import UIKit
import QuartzCore

@IBDesignable class VideoButton: UIButton {
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect)
    {

        let color2 = UIColor(red: 0.500, green: 0.500, blue: 0.500, alpha: 0.000)

        //// Oval Drawing
        var ovalPath = UIBezierPath(ovalInRect: CGRectMake(frame.minX + floor(frame.width * 0.03571) + 0.5, frame.minY + floor(frame.height * 0.03571) + 0.5, floor(frame.width * 0.96429) - floor(frame.width * 0.03571), floor(frame.height * 0.96429) - floor(frame.height * 0.03571)))
        color2.setFill()
        ovalPath.fill()
        UIColor.whiteColor().setStroke()
        ovalPath.lineWidth = 3
        ovalPath.stroke()


        //// Rectangle Drawing
        let rectanglePath = UIBezierPath(roundedRect: CGRectMake(frame.minX + floor(frame.width * 0.25714 + 0.5), frame.minY + floor(frame.height * 0.34286 + 0.5), floor(frame.width * 0.60000 + 0.5) - floor(frame.width * 0.25714 + 0.5), floor(frame.height * 0.64286 + 0.5) - floor(frame.height * 0.34286 + 0.5)), cornerRadius: 2)
        color2.setFill()
        rectanglePath.fill()
        UIColor.whiteColor().setStroke()
        rectanglePath.lineWidth = 3
        rectanglePath.stroke()


        //// Bezier Drawing
        var bezierPath = UIBezierPath()
        bezierPath.moveToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
        bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.34286 * frame.height))
        bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.64286 * frame.height))
        bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
        bezierPath.closePath()
        bezierPath.lineJoinStyle = kCGLineJoinRound;

        color2.setFill()
        bezierPath.fill()
        UIColor.whiteColor().setStroke()
        bezierPath.lineWidth = 3
        bezierPath.stroke()
        //  }

    }

}
Shannon Severance
  • 18,025
  • 3
  • 46
  • 67
C Almond
  • 65
  • 1
  • 3

3 Answers3

2

Change the references to 'frame' to 'rect' and it should draw in the device and simulator.

Astrodan
  • 21
  • 2
0

You should not be overriding drawRect: for a UIButton subclass. There is no need; you can customize the look of a UIButton using its various properties and methods. It is far from clear why you are doing this. (The fact that you are doing it, and not calling super, probably explains the problem; but the solution is not, call super, but rather, don't do it in the first place.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 1
    Why would you not override draw rect, surely this is better that adding another view to the button itself? – C Almond Feb 05 '15 at 15:38
  • Why would you need to add another view to the button itself? What are you actually trying to do? – matt Feb 05 '15 at 16:02
  • @matt I'm wondering the same thing, why would you not want to override the `drawRect`. For my use I'm making radial buttons. A solid circle when selected, then just the outline of a circle when not selected. I would think this is ideal for overriding `drawRect`. – random Aug 05 '16 at 19:46
  • @random UIButton is one of the most user-configurable of all interface classes. You say: "A solid circle when selected, then just the outline of a circle when not selected" UIButton gives you hooks for doing just that. You can set the selected background and the normal background. You can even override methods like `backgroundRect` or `imageRect` to change the size and placement under different circumstances. There is absolutely no need to interfere with the view's drawing. – matt Aug 05 '16 at 20:07
  • @matt I understand. Doesn't setting the selected background and normal background require an image? Are there any adverse effects to override the `drawRect`? So I use PaintCode to generate drawing code for the icons I make...my thought process was that it was more efficient than passing in images. I could definitely be wrong. Any feedback extremely appreciated!! :) – random Aug 05 '16 at 20:35
  • @random You can certainly use PaintCode. But use it to generate an image. I think your worries about efficiency are unfounded. UIButton _wants_ images! Make it happy. – matt Aug 05 '16 at 20:38
0

I have been trying to do a similar thing recently - create a subclass of UIButton, overriding drawRect() in order to draw a simple custom icon (I am making a play/stop button that alternates between "Play" and "Stop" on each tap):

Play Button

Stop Button

Maybe I don't know enough about iOS development yet, but in response to other answers and older posts online that discourage extending the UIButton class, I don't understand why this would be a bad idea. Of course you could customize a button by setting custom background images, but in my opinion this isn't as flexible as overriding drawRect (not to mention it can be a pain to edit your button anytime you want to change something because you have to edit an actual image instead of a few lines of code).

I'm sure there are other ways to achieve the same result (implement a button via a custom UIView listening for touch events, for example), but I think the cleanest and easiest way is still just to extend the UIButton class. After all, it is a subclass itself of UIView.

Regarding your code - it appears to work correctly in my environment, although I had to change the colors slightly to get it to show up against a white background (i.e. UIColor.blackColor().setStroke() instead of UIColor.whiteColor().setStroke()). Also, as @Astrodan mentioned, it might be a good idea to use rect instead of frame, since it is being passed to you (although the code worked with frame for me):

Live-rendered Storyboard in XCode:

Storyboard in XCode

On iPhone 6 Simulator:

enter image description here

Community
  • 1
  • 1
bodecker
  • 474
  • 5
  • 8