1

I recently purchased paintcode. I used this to create a slider. In Xcode, when I, In my storyboard create an empty view and set it to a class Slider.m where my slider code is, and run this app, this happens:

enter image description here

My drawing code is inside -

(void)drawRect:(CGRect)rect {}

My Slider.h is inheriting fram UISlider. If I inherits from say UIButton, only my drawing appears.

Why is that?

Jay
  • 6,572
  • 3
  • 37
  • 65
Nilzone-
  • 2,766
  • 6
  • 35
  • 71
  • There is generally no need to use custom painting (`drawRect:`) for customizing a slider. You can simply provide the graphic parts to its instance - see `setMaximumTrackImage:forState:` and alike. For a complete tutorial on that subject, you may want to use (the first google hit) http://www.getappninja.com/blog/how-to-make-a-custom-uislider – Till Dec 25 '13 at 11:15
  • @Till I appreciate the tip. But I still wanna know why this happens (an extra slider appears when inheriting from uislider) – Nilzone- Dec 25 '13 at 20:12
  • The reason is the fact that apple decided to use several subclasses within UISlider for all the UI handling (drawing, tracking, ...). As such, you drawRect method is rather pointless. Hence you should read about https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/UIKitUICatalog/UISlider.html#//apple_ref/doc/uid/TP40012857-UISlider and do as they suggest to - OR - create an entirely custom version by subclassing `UIView`. – Till Dec 25 '13 at 22:30
  • @Till this may be a dumb question, but I'm fairly new to IOS. Say I use my custom drawing code, and inherits from UIView, how would I go about getting all the different methods from the UISlider class? – Nilzone- Dec 25 '13 at 22:46
  • You would have to implement that entirely yourself, no inheritance. And that is, once again ;), the reason on why I urge you to use the standard UISlider and customize its appearance via the suggested methods. Have a look at the second link that I had supplied you with. – Till Dec 25 '13 at 22:48
  • @Till That does look easier! The reason I made it the way I did was when I made a button, and used it's drawing code, and inherited from UIButton everything worked out great :) Guess the UISlider is way different. Anyway - Thanks! – Nilzone- Dec 25 '13 at 22:53

1 Answers1

2

The displayed results are reasoned in the fact that UISlider (among many other controls) in fact is composed of multiple subclasses which handle the drawing themselves. The results is a highly optimized display code which can not properly be overridden using drawRect: on the UISlider only. You would have to override several other, partially closed implementations of that composed control.

In fact, there is a much easier and much more performant solution which is providing the graphical elements you wish to customize to UISlider. A nice introduction on that subject can be found on Apple's conceptual introduction to Sliders.

There some smaller pitfalls though - one of them is the fact that a UISlider's thumb does not "like" to be replaced by something with a different size. Those are however covered by many tutorials - one of those would be how-to-make-a-custom-uislider.

As a rule of thumb: avoid subclassing and overriding drawRect: when possible by any means as it will vastly degrade the performance of your UI.

Instead look at solutions that make use of the UIAppearance protocol for controls that do not provide interfaces for customizing. UISlider however does provide them, so go for those.

This would be my approach priority list:

  1. Check very carefully if the control in question does allow customizing by providing images etc.
  2. Check if the control in question adheres to the UIAppearance protocol.
  3. Use subclassing and possibly overriding drawRect:
  4. When it turns out that the control in question appears to handle drawRect: in a "weird" way, subclass UIView and recreate the missing logic yourself.
Till
  • 27,559
  • 13
  • 88
  • 122