iOS: Background image in UIImagePickerController is inconsistent with the rest of the app - objective-c

I'm using the following code to set the navbar's background:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"tile.png"] forBarMetrics:UIBarMetricsDefault];
This results in a nice tiled background such as you see here:
However, when I open up a UIImagePickerController, the background is warped somehow and we end up with something like this:
Anyone have suggestions on how to fix it?

Stretching instead of tiling: to Stop That
Create a class of type UINavigationBar
Create your custom UINavigationBar subclass.
Comment initwithFrameMethod
Add method DrawRect:
(void)drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed:#"bluebackground.jpeg"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
4.in AppDelegate.m, AppliocationdidFinishLaunching
Write
[self.navigationbar setValue:[[customBar alloc]init] forKeyPath:#"navigationBar"];
Adding Image By this way will not stretch the image
Refer this Link:
http://www.iosdevnotes.com/2011/09/custom-uinavigationbars-techniques/
http://designm.ag/tutorials/designing-a-custom-iphone-app-navigation-bar/
Hope this will help you.

Related

Using an LSR image on a UIButton

I am creating a tvOS app and I want to use parallax images on a couple of buttons. From the docs:
To incorporate parallax images in your app:
Create a UIImage object.
You load the image differently depending on whether the image is included in your app bundle or whether you have downloaded the
image.
Bundle—Load images using imageNamed:.
Downloaded file—Load images using imageWithContentsOfFile:.
Create a new UIImageView object using the loaded images.
If the UIImageView is part of another view, set adjustsImageWhenAncestorFocused to YES on the UIImageView.
I know it says UIImageView there, but I was hoping to make the same effect happen on a UIButton, like the home screen app icons.
I've created the artwork, made a stack in the asset catalog, and loaded the image with imageNamed:, but the UIButton does not behave like a parallax image. It does not sway around like the home-screen icons do. It just looks like a flat image.
Is there something else I have to enable in order for the UIButton to behave like the home screen app icons?
UIButton* quitGame = [[UIButton alloc] initWithFrame:rectWithNewX(playAgain.frame, 985)];
[quitGame setImage:[UIImage imageNamed:#"quit.lsr"] forState:UIControlStateNormal];
[quitGame setAdjustsImageWhenHighlighted:YES];
fadeIn(quitGame, self.view, 0.5);
As of right now, this is not possible with just UIButtons, however, I did find a workaround.
Instead, create a UIImageView that will fill the size of the UIButton and make it a subview of the UIButton. Then call the adjustsImageWhenAncestorFocused: and set it to true. Voila!
UIButton* playAgain = [[UIButton alloc] initWithFrame:CGRectMake(centerX(650, self.view), sh() - 250, 300, 180)];
[playAgain setAdjustsImageWhenHighlighted:YES];
[playAgain addTarget:self action:#selector(playAgain) forControlEvents:UIControlEventPrimaryActionTriggered];
fadeIn(playAgain, self.view, 0.5);
UIImageView* playAgainIGV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 180)];
[playAgainIGV setImage:[UIImage imageNamed:#"playagain.lsr"]];
[playAgainIGV setAdjustsImageWhenAncestorFocused:YES];
[playAgain addSubview:playAgainIGV];
I've had issues when setting files or precompiled LSRs.
Creating the LSR in XCode Asset Catalogue through Asset Catalogue -> New Apple TV Image Stack and dragging in the PNGs, then setting the image either through Interface Builder or through this works:
-(void) setLsr:(UIButton *)button lsrNamed:(NSString *)lsr {
[button setAdjustsImageWhenHighlighted:YES];
UIImageView *biv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, button.frame.size.width, button.frame.size.height)];
[biv setImage:[UIImage imageNamed:lsr]];
[biv setAdjustsImageWhenAncestorFocused:YES];
[button addSubview:biv];
}
Regarding the answer of david I made a simple Swift method to create a parallax effect button:
func createParallaxButton(button: UIButton, imageNamed: String) {
button.adjustsImageWhenHighlighted = true
let buttonBg = UIImageView(image: UIImage(named: imageNamed))
buttonBg.adjustsImageWhenAncestorFocused = true
buttonBg.frame = button.bounds
button.addSubview(buttonBg)
}
createParallaxButton(myButton, imageNamed: "myButtonimage.lsr")

How to properly position the back button in iOS7

I used this code to use a custom image as the back button in the whole app.
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:#"back"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:#"back"]];
The image dimensions are 30 x 30.
The code adds the image as the back button but the position is not the correct, as you can see in the following image:
Any ideas on how to properly position the image without modifying its dimensions (at least the visual part of the image (circle + arrow))?
EDIT:
I don't want to use a custom back button because that forces me to disable the swipe/back-gesture in iOS7
EDIT
I think I might have found the trick (in iOS 7 Design Resource -- UIKit User Interface Catalog.)
Under Bar Button Items
Note that a bar button image will be automatically rendered as a template image within a navigation bar, unless you explicitly set its rendering mode to UIImageRenderingModeAlwaysOriginal. For more information, see Template Images.
Under Template Images they have some code to specify the UIImageRenderingMode.
UIImage *myImage = [UIImage imageNamed:#"back"];
UIImage *backButtonImage = [myImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// now use the new backButtomImage
[[UINavigationBar appearance] setBackIndicatorImage:backButtonImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backButtonImage];
Try creating the UIImage with alignment insets and then set the Back Indicator image.
UIEdgeInsets insets = UIEdgeInsetsMake(10, 0, 0, 0); // or (0, 0, -10.0, 0)
UIImage *alignedImage = [[UIImage imageNamed:#"back"] imageWithAlignmentRectInsets:insets];
[[UINavigationBar appearance] setBackIndicatorImage:alignedImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:alignedImage];
You might also try adjusting the position of the UINavigationBar title text
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics];
Well just follow one of the suggestions to fix the layout and lose the iOS 7 "back gesture", and then fix it with a UIScreenEdgePanGestureRecognizer!
A UIScreenEdgePanGestureRecognizer looks for panning (dragging) gestures that start near an edge of the screen. The system uses screen edge gestures in some cases to initiate view controller transitions. You can use this class to replicate the same gesture behavior for your own actions.
PLEASE SEE EDIT BELOW!!!
I created a custom back button in iOS7 not too long ago. Mine has an arrow and the word back on it. I do think pawan's suggestion is a good start. To create the back button with your custom image you can use,
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButtonClicked)];
[backButton setBackgroundImage:finalImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];
self.navigationItem.leftBarButtonItem = backButton;
My image finalImage is a composite of two different images, but you can just use your "back" image. But I think that is where the problem lies. My image was a composite, you might want to make a composite as well, but put a clear space above your back icon. I placed a clear space to the right of my icon to adjust it's spacing. Here is the code,
UIImage *arrow = [UIImage imageNamed:#"back.png"];
UIImage *wordSpace = [UIImage imageNamed:#"whiteSpace.png"];
CGSize size = CGSizeMake(arrow.size.width + wordSpace.size.width, arrow.size.height);
UIGraphicsBeginImageContext(size);
[arrow drawInRect:CGRectMake(0, 0, arrow.size.width, size.height)];
[wordSpace drawInRect:CGRectMake(arrow.size.width, 0, wordSpace.size.width, wordSpace.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The Image wordSpace is a clear png that I made in photoshop so my new back button image was not stretched. You might want to place a clear png on top, to push the icon down a little. Make the size.height of it in photoshop for what you think the adjustment should be. You might need to futz with this a bit. And make sure to change up the CGSize so that it fits your icon and the clear space.
My word back was a bit off, so I looked at
[backButton setTitlePositionAdjustment:UIOffsetMake(-20, 0) forBarMetrics:UIBarMetricsDefault];
I had to play around with that line a bit to make it look as good as possible but it finally gave me what I wanted with the -20. I even adjusted the second variable which is 0 in mine, this moved the actual icon around. -5 put the icon down way to far, but its another option from the clear png.
Now to deal with the fact that you want it to be an actual back button. Look at the first line of code I posted. The action on the button is #selector(backButtonClicked). So all you need to do is make that method and you should be good to go!
- (void)backButtonClicked
{
NSLog(#"going back");
[self.navigationController popViewControllerAnimated:YES];
}
Hope this helps a bit.
EDIT*****
I was playing around with my code a little bit and found a better way to move the back icon. I just used a ship's wheel because I didn't have the same one that you did, but it will work the same.
Since you don't really want a title you can create the button with this code,
UIImage *image = [UIImage imageNamed:#"781-ships-wheel.png"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:#selector(backButtonClicked)];
Just change the 781 stuff with your icon's name. Then you can move it around with the following,
[backButton setImageInsets:UIEdgeInsetsMake(20, 0, -20, 0)];
Take a look at this picture.
This shows the icon down considerably, but I wanted to show you the idea. The numbers for the Edge insets are Top, Left, Bottom, and Right. Don't touch the left and right if you don't need to move it that way, change the top and bottom. Notice however, that if you need to move it down by 20 points like I did, (way too much) you need to offset in the negative for the bottom, or the icon will get compressed. This is what it looks like with all zero's.
So you can pretty much move it where ever you want, but you will still have to set up the #selector(backButtonClicked) to make it work like the real back button.
This is Swift 2 version.
The simplest way is like this. Put this code in AppDelegate.'
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navigationBarAppearace = UINavigationBar.appearance()
let image = UIImage(named: "back-btn")
navigationBarAppearace.backIndicatorImage = image
navigationBarAppearace.backIndicatorTransitionMaskImage = image
return true
}
if your back button has background colour, it may won't work correctly.
Add your icon to asset folder for each resolution like this:
You can try this
self.navigationItem.leftBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 0, 10, 0);
The problem is that your image is too tall. To prove this, first try this code:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,20), NO, 0);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(6,0,4,20));
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorImage = im;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,20), NO, 0);
UIImage* im2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorTransitionMaskImage = im2;
It looks fine. Now change the 20 to 30 in the two CGSizeMake calls:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,30), NO, 0);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(6,0,4,20));
UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorImage = im;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(10,30), NO, 0);
UIImage* im2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.navbar.backIndicatorTransitionMaskImage = im2;
The icon is now too high.
So just make your image 20 pixels tall and all will be well.
UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, -2, 0); // or (2,0,0,0)
UIImage *backArrowImage = [[UIImage imageNamed:#"back"] imageWithAlignmentRectInsets:insets];
[[UINavigationBar appearance] setBackIndicatorImage:backArrowImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:backArrowImage];

Can't remove shadow from UINavigationBar

I can't remove the shadow from my UINavigationBar for some reason on iOS6. Why isn't this working? I've tried the following:
if ([[UINavigationBar appearance]respondsToSelector:#selector(setShadowImage:)]){
[[UINavigationBar appearance]setShadowImage:[[UIImage alloc] init]];
}
if ([[UINavigationBar class]respondsToSelector:#selector(setShadowImage:)]){
[[UINavigationBar appearance]setShadowImage:[[UIImage alloc] init]];
}
You have to do the work on a NavigationBar instance...
if ([navigationBarInstance respondsToSelector:#selector(setShadowImage:)]){
[navigationBarInstance setShadowImage:[[UIImage alloc] init]];
}
Edit:
If you for some reason really need to perform the check on the class. This will work:
if ([UINavigationBar instancesRespondToSelector:#selector(setShadowImage:)]) {
}
This had me stumped for a while until I read the docs!
NOTE:
For a custom shadow image to be shown, a custom background image must also be set with the setBackgroundImage:forBarMetrics: method. If the default background image is used, then the default shadow image will be used regardless of the value of this property.
Mike Pollard has it right.
To remove the shadow underneath the UINavigationBar on iOS 6, you need to set a custom background image in addition to setting the shadow image to a blank UIImage.
CustomViewController.m
- (void)viewDidLoad
{
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"Background"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
}
In the above example, "Background" would be a PNG image in your project.

UIView background image not rotating

I've got an app that has two different background images. The one selected is determined by the orientation. When I start out, I check self.interfaceOrientation, and then go and pick the proper image. However, whenever the view opens, part of the image repeats instead of stretching. I saw a previous answer applying autoresizing masks to an imageview, but there is no imageview that I'm currently using.
Inside the loadView method:
if(self.interfaceOrientation==UIInterfaceOrientationPortrait ||self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed: #"portrait"]]];
}else{
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed: #"landscape"]]];
}
As rishi had pointed out, the issue was caused by the colorWithPatternImage method. What I did to resolve this was to set the background of the view to be a specified image.
UIImageView* bgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed: #"foo.png"]];
[self.view addSubview: bgView];
I also added in flexible width and height so that it would rotate properly.

Add a background image to TTWebController's UIToolbar

I would like to add a nice background image to the UIToolbar of a subclass of Three20's TTWebController.
Since I don't mind all UIToolbars of my app sharing the same background, I tried using UIColor colorWithPatternImage in my style sheet and that doesn't seem to work (toolbar end up solid black).
I've also tried doing something like this:
#implementation UIToolbar (MyCustomToolbarBG)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: kBackgroundImage];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
with little success..
I certainely don't want to copy and paste the entire TTWebController code just to make my own class out of it since I actually don't modify anything else, but I don't really see anything else I can do. Anyone have a suggestion?
Ok, found my way like this: I subclassed the TTWebController to subclass the loadView: method.
-(void)loadView{
[super loadView];
[_toolbar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed: kBackgroundImage]] autorelease] atIndex:0];
}
Better than nothing. Not extremely handy if they decide to change anything about the protected attribute _toolbar though...