![]() At first it looks like one could layer multiple linear gradients to get the correct result, but in fact that’s not possible. With the circle done, the next head scratcher was on how to do the complex gradient inside the saturation/brightness box. This by the way works even more efficient than manually drawing the circle into a UIImage and then drawing that image in UIView::drawRect. A Core Animation Layer nicely caches the rasterized image of the circle and saves us from many drawing all those individual segments again. The hue circle for example only has to be redrawn when the control size changes, not when the user changes the color values. So I scrapped that idea and instead of overwriting UIView::drawRect, I implemented three custom Core Animation Layers, one for each element in the control. However, when the user starts modifying the hue/saturation/brightness values, I had to draw the whole control over and over again and drawing all those segments slowed down the UI considerably. My initial design of the control used a class derived from UIView that did all the drawing by overwriting UIView::drawRect. ![]() Okay, the last point requires some more explanation. ![]() This was easily solved by using the proper trigonometric functions. The reason for this is that the calculation of the segment vertex positions is done using the circle perimeter (for an x-offset) and the radius (for a y-offset), neglecting the fact that such a point will not lie on the circle itself! It simply does not follow the curvature of the circle. As some commentator noted, when the number of subdivision isn’t quite high, gaps between the segments are noticeable.When the number of subdivisions is small, we don’t have a circle but some n-gon shape. The code draws sort of a skewed rectangular shape and rotates it around the center of the control.There were however three problems with that code: If the number of segments is high enough, it looks like a smooth gradient. Unfortunately, Core Graphics can only draw linear gradients and so some folks over at StackOverflow proposed the solution I’m also using: Drawing a number of circle segments, each with a flat color. However, I wanted the control to work on various resolutions so Core Graphics was the obvious candidate. The easy way to do this would be to generate it in Photoshop and then bake it into an image. The first part I started with is the hue circle. The screenshot is taken from the custom jersey configuration in StreetSoccer. Note that the black background and the shape do not belong to the control itself but to a UIPopoverController that simply hosts the ColorPicker. ![]() The two current value markers (gray circles).The control itself consists of four parts: What we are about to set off to is a journey on how to create a basic hue/saturation/brightness circular color picker like in the screenshot above. So a couple of days ago when I needed a color picker for Streetsoccer, I found myself in the situation of having to write one myself and I thought I spare everyone the trouble of going through the process by writing this post. Even worse, when looking for some code snippets to base a custom implementation on, those snippets had bugs! Kind of feels like the stone ages, but on the other hand, C#/WPF doesn’t have a stock color picker either… Things like this surprise me: How many years has it been since the first iPhone SDK came out? They just announced iOS 7 and I haven’t checked it out yet, but in iOS 6 at least, there is still no color picker control! When doing some googling, there are a number of people that have implemented custom color picker controls but none of those seemed to be simple to use or looked okay visually. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |