iOS 7 Universal Back Button Image - ios7

This has been covered disparately in other questions and answers but this is a more general request for advice.
I am writing a scientific App so the titles in the Navigation Bar have a habit of being long. So I need to contrict the size of the back image or text.
If I do this at the View Controller level it works perfectly but it means inserting the code in every VC. E.g.
UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 60.0f, 36.0f)];
UIImage *backImage = [[UIImage imageNamed:#"backButton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12.0f, 0, 12.0f)];
[backButton setBackgroundImage:backImage forState:UIControlStateNormal];
[backButton setTitle:#"" forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(popBack) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backButtonItem;
As I want this to be consistent what is the best approach in iOS 7 to put it in the App Delegate so it is only instigated once?

The best approach in my opinion would not be to put this in the App Delegate, It would be to create a subclass of uiviewcontroller and add it there in the viewwillappear than have all the view controllers in your app of "that" kind.

Related

Right bar button item not aligned vertically

I am setting a rightbarbuttonitem in from a viewController using the following code:
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveDetails)];
self.navigationItem.rightBarButtonItem = item;
It is appearing as shown in the image:
As you can see, the button which appears is not vertically aligned with either th leftbuttonitem or the title.
I also tried adjusting the alignment using the code mentioned here:
[self.navigationItem.rightBarButtonItem setTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault];
But this removes the custom font and moves the button even higher.
How can I set a rightbarbuttonitem which is aligned AND maintains the custom font set using the UIAppearance proxy?
EDIT:
I even tried using
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:#selector(saveDetails)];
but the result is exactly as shown in the first image.
UPDATE (Sep 20):
It seems that I will have to go with Alexander's answer, anybody with a cleaner solution?
You can use the next variant:
UIButton *saveButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 20)];
[saveButton addTarget:self action:#selector(saveDetails) forControlEvents:UIControlEventTouchUpInside];
[saveButton setTitle: #"Save" forState:UIControlStateNormal];
[saveButton setTitleEdgeInsets:UIEdgeInsetsMake(5, 0, 0, 0)];
UIBarButtonItem *item =[[UIBarButtonItem alloc] initWithCustomView:saveButton];
self.navigationItem.rightBarButtonItem = item;
I tried the answer but didn't seem to work.
The solution for me was adding UIButton as UIBarButtonItem. If it sounds confusing, just drag a UIButton from Interface Builder to the position of Left or RightBarButtonItem on the navigationBar in your storyboard.
Hope it helps.

UIButton in SMS App

How can I recreate the UIButtons displayed at the top of the SMS app (such as the "Load Earlier Messages" button). They look like pretty standard UIButtons except with a gradient, a slight shadow drop shadow and inner shadow, and a bluer border. Does Apple use a stretchable UIImage to make these or are they created programmatically (and how)?
My favorite solution to this problem is to create a segmented control with exactly one segment. You end up with a nice-looking button. Here's how I do it programmatically:
UISegmentedControl* takePhotoButton =
[[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Take Photo"]];
takePhotoButton.segmentedControlStyle = UISegmentedControlStyleBar;
takePhotoButton.frame = CGRectMake(55,336,110,38);
takePhotoButton.tintColor = [UIColor lightGrayColor];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIFont boldSystemFontOfSize:16]
forKey:UITextAttributeFont];
[takePhotoButton setTitleTextAttributes:attributes
forState:UIControlStateNormal];
takePhotoButton.momentary = YES;
[takePhotoButton addTarget:self
action:#selector(onTakePhoto:)
forControlEvents:UIControlEventValueChanged];
[self.view addSubview:takePhotoButton];

iOS dynamic addition of UIControls

I'm trying to add a bunch of UIButtons to a screen at runtime. Based on user input I want to show different buttons in different locations. Is this possible?
Yes, it's possible.
Creating a button in objective-C:
UIButton *btnPrefix = [UIButton buttonWithType:UIButtonTypeCustom];
[btnPrefix setFrame:CGRectMake(0, 0, 20, 20)];
[btnPrefix setUserInteractionEnabled: YES];
[btnPrefix addTarget:self action:#selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview: btnPrefix];

Distorted custom Navigation buttons on non-retina display (using stretchable image method)

I am adding custom navigation buttons to my navigation bars via the following code.
//Instance method in CustomNavButton Class
-(UIButton*)setupButtonWithImage:(UIImage*)image andFrame:(CGRect)frame
{
UIButton *button = [[[UIButton alloc]initWithFrame:frame]autorelease];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake((frame.size.width-20)/2, (frame.size.height-20)/2, 20, 20)];
imageView.image = image;
UIImage *buttonImageNormal = [UIImage imageNamed:#"customBtn_black"];
UIImage *stretchableButtonImageNormal = [buttonImageNormal
stretchableImageWithLeftCapWidth:12 topCapHeight:0];
button.titleLabel.font = [UIFont boldSystemFontOfSize:12];
[button setBackgroundImage:stretchableButtonImageNormal
forState:UIControlStateNormal];
[button setTitleShadowColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button addSubview:imageView];
return button;
}
//Call CustomNavButton and add to Navbar
- (void)viewDidLoad
{
[super viewDidLoad];
//Add left invite friends button
CustomNavButton *leftButton = [[CustomNavButton alloc]initWithImage:[UIImage imageNamed:#"friends_1"] andFrame:CGRectMake(0, 0, 40, 32)];
[leftButton.customNavButton addTarget:self action:#selector(inviteButtonPressed) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:leftButton];
self.navigationItem.leftBarButtonItem = leftBarButton;
[leftButton release];
}
The navigation buttons appear fine on my iPhone (IOS5 with Retina Display)
However, the buttons look distorted on my simulator (or non-retina display)
How can I resolve this? How can I display the buttons properly even for non-retina displays?
Note that I have created the #2x buttons for this as well
EDIT:
It seems like the issue likes with the stretching of the image
UIImage *stretchableButtonImageNormal = [buttonImageNormal
stretchableImageWithLeftCapWidth:12 topCapHeight:0];
If I change the leftCapWidth value to 0, the buttons on the simulator looks better (but still bad).
But by doing this, it will cause my retina display button look a little distorted (seems like I can't win).
Can anyone advise if the problem does really lie here, and how I can alter the values so that it works well for both retina and non-retina displays?
Do you have two files? MyImage.png and MyImage#2x.png? It looks like the system is trying to resize the #2x file by scaling it down, which usually causes some jaggedness like this when it is simply scaled down.
MyImage.png should be half the size of MyImage#2x.png.
Your not setting the file format .png or whatever it is you have. And as Chris said you need two files regular and #2x.

UIButton like in UIActionSheet

I would like put UIButton on my UIViewController with style like have buttons in UIActionSheet. What should i add here:
UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom];
[ button setFrame: CGRectMake(10, 10, 50, 35) ];
[button setTitle:#"Button from UIActionSheet" forState: UIControlStateNormal];
[self addSubview: button];
You need to get the background image from somewhere and then set it using: - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state
I believe the .psd linked here has the action button background image http://media.photobucket.com/image/uiactionsheet%20button%20psd/visionwidget/iphone-gui-psd-file.jpg
you can using segmented control - very good trick
segmented = [[[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Info",#"Configuration", nil]] autorelease];
[segmented addTarget:self action:#selector(changeView:) forControlEvents:UIControlEventValueChanged];
segmented.tintColor = [UIColor colorWithRed:0.20 green:0.20 blue:0.52 alpha:1.0];
segmented.segmentedControlStyle = UISegmentedControlStyleBar;
Maybe exists some simple way like set some property?
Here is a post on using Apple's private UIGlassButton class.
You can't submit an app like this to the app store, but you can capture the generated background image to reuse in your published apps.