I have an UIButton subclass and I need its look
to be identical to an UIBarButtonItem when placed on the
classic blue tinted navigation bar.
The UIBarButtonItem has a border with a kind-of gradient,
being darker at the top and blue-ish at the bottom, which
I suspect it's done with some alpha trick. The bottom
looks recessed too.
There's also some overlay which makes the button a little bit darker
and even more when in the selected state.
Can anyone help?
The short answer is that you are going to have to spend some time learning how to draw gradients and shadows in Core Graphics.
The relevant documentation is called "Quartz 2D Programming Guide".
After you learn how to draw shadows and gradients, you are going to have to spend quite a bit of time zoomed in comparing what you are drawing vs what the button looks like.
You didn't ask, but this is what I would do:
Subclass UIBarButtonItem and add your custom functionality in there. Let UIBarButtonItem draw itself.
It might be easier for you just to use a photoshopped image. Use the image for your button. This way you don't have to worry about custom drawing code.
You can use Three20 library,
specially have a look at sample TTCatalog app.
Look at the source file "StyleTestController.m"
https://github.com/facebook/three20/blob/master/samples/TTCatalog/Classes/StyleTestController.m
I'm sure you'll find your answer here.
Cheers,
Related
I am trying to make an app that can annotate PDFs.
What I have done, is add the PDF through a UIWebview, so my main UIViewControllerhas a UIWebView Delegate.
What I am trying to do is put my drawing layer, which is a UIView over the top of my PDF view.
I have tried setting the background colour to "clearColour" and the opaque property to no, I still get a weird affect.
I think the issue might be because of drawing a bitmap onto the UIView, but I would still like some insight, or an example if one exists.
Thanks.
This is an image of the problem, the little white band at the top is the PDF, the white box is the UIView which I am drawing on.
The code I used for the "drawing code" is here, see "SmoothedBIView"
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_freehand-drawing/
Sorry, just noticed you had two questions. Again maybe this project can help you.
I want to draw UIButton in following shape :
I have cut the image, so the edges are not straight. Please consider them straight. Also the bottom right corner is as shown. It is cut in quarter of circle.
I am not able to draw this shape for UIButton. How to do this?
Interesting question. I did a search and found two simple solutions that seem much simpler than the GB2. They override either hitTest:withEvent: or pointInside:withEvent: to take into account if the current pixel is transparent or not. So just take your image, set the lower right corner to transparent in a graphics editor, and use one of these classes.
http://iphonedevelopment.blogspot.com/2010/03/irregularly-shaped-uibuttons.html and
http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone/
[self.myButton setBackgroundImage:[UIImage imageNamed:#"myOddlyShapedImage"] forState:UIControlStateNormal];
I got the same problem, I found a different UIBUtton libraries and solved this
search for:
GB2ShapeCache
and implement if you don't find it I could upload it and I give you the link.
You only put the library in your UIBUtton and it will work
I hope it helps :)
I often get given mockup images that define how an iPhone app is supposed to look. These can come from as many different methods as there are projects, sometimes balsamiq or even hand-drawn, sometimes Photoshop. One thing that is common is a bar tint color specified usually to match some corporate branding or overall app design.
If I open one of these design images in an app and use the paint dropper tool to get the RGB value for a color there are many places to do it, from the darkest regions at the lower edge of included buttons to the lightest regions at the top of the bar. I can't find a place to sample the color where the programmed result matches the mockups, it is always wrong in some regard leading to me squinting at two images trying to tweak one or more color values so they match well enough.
Given an sample of how a client imagines a navigation bar should appear*, how do you determine the right UIColor to apply to a bar's tintColor attribute?
*ignoring mockups containing rainbow effects, misapplied gradients and other flights of fancy. Matching color and brightness along the centre line would be good enough. That's at least a defensible position - "What you ask for just isn't how iOS works!"
Set up an app with a UINavigationBar/UIToolbar and three sliders to set the tintColor. Move the sliders around until it looks right.
If you also bring the image into the app somehow (UIPasteboard or stick it in a resource), using -[CALayer renderInContext:] and some CoreGraphics magic (kCGBlendModeDifference and something to multiply the differences; I forget what I used) you can even compare the two images.
Simulator note: You will first need to do Cmd-C to "paste" from the Mac pasteboard into the simulator pasteboard.
What I found was that you can't reproduce the default gradient on both the iPhone and iPad except with a tintColor = nil (the iPad default also has no "shine"). You can get reasonably close, but then the Done button colour is all wrong.
Usually I sample in the middle of the mock-up nav bar.
Excellent question which I don't have a direct answer for, but do have a solution.
Usually when I get designs the navigation bar doesn't really look like the iPhone's nav bar with a tint. The gradient is usually different as well. The way I see it, there are two ways to go:
Get the app sort of like the design
Get the app exactly like the design
Most of the times I get it almost like the design, which usually means sampling the color used in the mockup and using it as a tint color (or maybe a slightly lighter version of it).
If I really want to get it exactly right the way is to replace the default nav bar drawing with an image.
Just create a category for UINavigationBar and override drawRect. This works surprisingly well and most times the default buttons will be the color you need and blend right in without extra work.
In any case in my experience getting your app to look exactly like the designer's work is a lot of work that's usually overlooked. But when done properly it's totally worth it.
In the example below I needed to support two different nav bar looks for two different sections of the app, so I used the view's tag property to check which version to use.
#implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image=nil;
if (self.tag == 0)
image = [UIImage imageNamed: #"navBarDesign1.png"];
else if (self.tag == 1)
image = [UIImage imageNamed: #"navBarDesign2.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Elaborating on tc.'s answer, here's a free app in the AppStore I found for doing just this, called "BarTint"
http://www.appstore.com/bartint
I always put the style to "Black Opaque" (if I work with Interface Builder) and then sample the darkest color in the design (usually regions at the lower edge) and put that color as tint. This gives me something really similar, BUT of course doesn't allow me to control the light (reflection) side. If the client really wants the exact gradient, I use a image (unfortunately)...
Is there any way to define which area of a UIButton is clickable? In my case I would like to have PNGs with an alpha channel overlapping. These PNGs should act as buttons - but only where alpha is > 0. Is there a way?
Best
Stefan
Don't do that. According to the Apple Human Interface Guidelines, all UI elements should behave in a consistent manner.
OBShapedButton is an awesome project that will give you a button that will only respond to taps that are in the images area. I've messed with Irregularly Shaped UIButtons and I think OBShapedButton is a little more accurate. Not trying to bash on the other one at all. I've used the other and it works just fine. I've just seen a more accurate hit area with this one.
I'm trying to place a red tint on all the screens of my iPhone application. I've experimented on a bitmap and found I get the effect I want by compositing a dark red color onto the screen image using Multiply (kCGBlendModeMultiply).
So the question is how to efficiently do this in real time on the iPhone?
One dumb way might be to grab a bitmap of the current screen, composite into the bitmap and then write the composited bitmap back to the screen. This seems like it would almost certainly be too slow. In addition, I need some way of knowing when part of the screen has been redrawn so I can update the tinting.
I can almost get the effect I want by putting a red, translucent, fullscreen UIView above everything. That tints everything red within further intervention on my part, but the effect is much "muddier" than results from the composite.
So do any wizards out there know of some mechanism I can use to automatically composite the red over the app in similar fashion to what the translucent red UIView does?
I managed to somewhat make this work but with some side-effects:
I setup a UIView on top of all my app-views (attached to the window) which is not userInteractionEnabled and which is opaque
This UIView carries some custom drawRect-method which first fills the complete area with red color and then after having made a "screenshot" of my window-viewhierarchy I am rendering this image with
CGContextSetBlendMode( c, kCGBlendModeMultiply);
to the UIView.
To constantly update this UIView to the current state of the apps UIViews I constantly produce "screenshots" and render them as fast as possible.
I setup an NSTimer which is doing this snapshotting/rendering in a defined frequency and which is added to the the NSRunLoop for "Tracking".
RESULT: some really laggy response from the UI with several fancy effects, but still usable though if you do not set the frequency of snapshotting/rendering to high.
See screenshot here...
The result looks okay, but the usability really suffers a lot. I had a look at the OpenGL-examples before trying this aproach, but OpenGL is a whole lot of different (mostly C) code which seems to be very near to the hardware and which gives you a real headache.
So, the described approach is what I will shoot for with my next app. I hope Apple accepts it even though it degrades UXP during nightvision mode. They should simply make CALayer filter-backed then my problem will definitely be solved a whole lot better and performing nicely.
You could try this: subclass UIView. Add code to -drawRect method to draw the overlay. Make your UIView subclass pose as UIView everywhere in your app with
class_poseAs ([CustomUIView class], [UIView class]);