iOS Buttons - add border - ios

I am making my app ready for iOS7. I did conversion and was working with a user. The button in the app does not look like button. Looks very flat. Is there someway to put border or make it stand like a button?

Try this for adding border, It will work
#import <QuartzCore/QuartzCore.h>
then in viewDidLoad
_btn.layer.borderWidth=1.0f;
_btn.layer.borderColor=[[UIColor blackColor] CGColor];
_btn.layer.cornerRadius = 10;
also you can fill the color for making appearance somewhat like button, or best way is to use image there
Apart from BorderColor, you can do it by using Runtime attributes too.

try this , this will set border to button
#import <QuartzCore/QuartzCore.h>
btn.layer.borderColor = [UIColor blackColor].CGColor;
btn.layer.borderWidth = 1.0;
btn.layer.cornerRadius = 10;

With Swift and XCode 6 you can do this.
Click the UIButton element in Storyboard, and go to identity inspector. In the user defined runtime attributes, enter:
layer.borderWidth number 1
If you want nice looking corners
layer.cornerRadius number 5
layer.maskToBounds boolean true
Now this will give you a border but to set the colour you need to do it with code. Go to your view controller, and add an IBOutlet from your button. Note that in this case it's an IBOutlet, not an IBAction. Say you do,
#IBOutlet weak var xButton: UIButton!
Call this in the viewDidLoad function like below to set the colour.
xButton.layer.borderColor = UIColor.whiteColor().CGColor
Thanks!

The design principles in iOS7 have changed. However, if you want to go flatter, but still want a custom button that "stands like a button", you can try out this open source component collection:
FlatUIKit on GitHub

There are two way to simplify button in ios 7
1>Set image : Just like Button using setImage Property for button
2>Set bordercolor borderWidth :
button.layer.borderWidth=1.0f;
button.layer.borderColor=[[UIColor blackColor] CGColor];

I suggest you try one of the iOS BootstrapButton libraries (or clones). Just change UIButton in the storyboard to BButton. There is just no preview in the storyboard.
http://github.com/katzlbt/iOSBootstrapButton
http://github.com/katzlbt/iOSBootstrapButtonDemo
http://github.com/mattlawer/BButton

If you use a background image, move button backward.
Editor>Arrange>send backward

In ios7 buttons are supposed to look borderless. Please see apple's View Transition Guidelines for help.
If you REALLY want the buttons to have a border, do: [button setImage:forState:] to set a customized button image with border.

Related

Button with border (most optimized)

In my app I need to create a button with a 1px colored border with a corner radius. Width may be different.
Naturally I will create a UIButton setting its layer.cornerRadius and layer.borderWidth.
Is it optimal?
Is there a betterway to achieve this?
Another developer told me that doing this way is expensive.
What do you think?
Thanks.
Subclass UIButton. May be named ViewWithThinBorder .
In its implementation in awakeFromNib method add border corner and width properties.
Now you can go to interface builder select button and set its class to ViewWithThinBorder from identity inspector.
This is not only optimized its more reusable anywhere around the interface builder. Also you can change buttons around all view hierarchy from central location.
#import "ViewWithThinBorder.h"
#implementation ViewWithThinBorder
-(void)awakeFromNib
{
self.layer.borderColor = [UIColor groupTableViewBackgroundColor].CGColor;
self.layer.borderWidth = 1.0f;
self.layer.cornerRadius = 1.0f;
}
#end

Create a transparent UIView with some information in it

In my app I take a picture then I add on this picture weather forecast and position with some UILabels and some UIImageviews. For now I'm getting picture like this:
But I will create something like the following picture:
Does anyone ions how to do a stuff like the second picture?
In other word I've to create a transparent section in which I will show the weather forecast, the position and the date.
I hope you can help me
You need to create this hierarchy to create view.Set Alpha as you want.
Wherever u set the view, just add this for example:
yourView.backgroundColor = [UIColor darkGrayColor];
yourView.alpha = 0.5;
U can change the background color to whatever u want...
Notice!
The alpha will effect also the subviews of yourView.
So u can play with it, with some views with transparent backgrounds above yourView..
Good Luck!
If you simply want to set a backgroundColor with transparency (not translucency), you assign background color like this:
yourView.backgroundColor = [[UIColor darkGrayColor] colorWithAlphaComponent:0.5f];
If this is inside UIImagePickerController, you might want to check out the cameraOverlayView property of UIImagePickerController`.
You can add the view layer for achieving this kinda effect in your view controller like i would do if i have to
Maybe you should try changing the background colour of the view. For example make it black and add an alpha value.
For Example:
[yourview setBackgroungColor = [UIColor colorWithRed:<#(CGFloat)#> green:<#(CGFloat)#> blue:<#(CGFloat)#> alpha:<#(CGFloat)#>]];

iOS custom shape navigation bar

I want to developer app with a custom navigation bar like in the following images:
I think that i need to subclass UINavigationBar and add button to centre of nav bar, but i don't really know how to make navigation bar look like on image. Can you please give me advice what should i do, links to any kind of documentation would be awesome!
Similar questions about navBar that doesn't helped me:
ios back button in the bar
Use custom Navigation Bar in iOS
Custom Navigation Bar in iOS 5
rogcar
EDIT:
My idea is next: make custom navigation bar height little bigger than default size, and add background image with arrow in it and with some transparency on the edges.
If you want a button (you probably do want) you can achieve it completely by subclassing UINavigationBar. You should remember that height of UINavigationBar is read-only property.
Style but not tappable:
So let's assume we subclass the navigation bar and add button there. You could do this and it will be going look great. For example:
- (void)drawRect:(CGRect)rect
{
self.backgroundColor = [UIColor lightGrayColor];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width/2-50, 0 , 100, 100)];
[myButton setBackgroundColor:[UIColor lightGrayColor]];
[myButton setTitle:#"Normal" forState:UIControlStateNormal];
[myButton setTitle:#"Highlighted" forState:UIControlStateHighlighted];
[self addSubview:myButton];
[self sendSubviewToBack:myButton];
}
But you will facing a problem that your button is non tapeable below UINvaigationBar. (I post an image on the bottom of the answer)
So there is clearly not a path you want to follow. Don't even try that.
Style but not tappable 2:
You may override this method in your navigation bar subclass
- (CGSize) sizeThatFits:(CGSize)size {
return CGSizeMake(custom_width, custom_height);
}
And then mask it using UIBezierPath for example
The right (tappable) way:
You have to create a view stick to your UINavigationBar. What i will do here (if you want it to every screen) is:
Make a Category of UIViewController which can draw (for example - this is easiest way) UIButton.
Style this 'UIButton' whatever you want (if you want
Pin action to 'UIButton': [btn addTarget:self action:#selector(menuShow:) forControlEvents:UIControlEventTouchUpInside];
menuShow: method should be declare in your category
You can call drawing button every time you want to redraw view controller.
As you can see there there will be two separates View: UINavigationBar and UIButton. This is allow you to set content under this little button and make it tapable.
So why just don't hide navigation bar, and use different view? Because iOS7 ;) When Apple change it in iOS7 for example then you have to rebuild your pseudo NavigationBar, with only additional view, you don't need to do anything.
You do not need to subclass UINavigationBar. Create UIView add to it UIImageView as background with image in the shape you need, add button.
Subclass UINavigationController hide UINavigationBar, add custom navigation bar.
First Hide navigation bar using -
self.navigationController.navigationBarHidden = YES;
Then create UIView with required height,height of navigationBar is 44px.Then create background image view, object of required UIButton and add all objects on created UIView as a subview.It will look like navigationBar.Thank you.
You can add your custom shaped view as titleView on the navigation bar.
Just make sure that clipsToBounds is set to NO, so it doesn't get clipped.

UISegmentedControl does not respect divider images set for UIControlStateDisabled

I'm using the new UIAppearance API in iOS 5 to style a UISegmentedControl with custom graphics. I need to be able to set some segments to be disabled at times during execution, but the UIAppearance methods don't seem to allow me to set a divider image for the UIControlStateDisabled state.
I'm calling:
[[UISegmentedControl appearance] setDividerImage:disabledSelectedImage
forLeftSegmentState:UIControlStateDisabled
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
where disabledSelectedImage is a resizable image from this resource:
Yet when I set the left segment to be disabled ([UISegmentedControl setEnabled:forSegmentAtIndex:]), the result is this:
You can clearly see that the UISegmentedControl has defaulted to use the UIControlStateNormal-UIControlStateNormal divider image.
It seems perfectly happy for me to set a background image using UIControlStateDisabled
[[UISegmentedControl appearance] setBackgroundImage:disabledImage
forState:UIControlStateDisabled
barMetrics:UIBarMetricsDefault];
(and respects the image I supply while in the disabled state) but not a divider image. Has anyone come across this or found a solution?
I've decided that this must be an iOS bug and have filed a radar with Apple. My solution to the problem for now is to remove segments, rather than disabling them.
A bit of an ugly workaround but i managed to fix it with the following until apple fixes it itself.
First you need to subclass UISegmentedControl and add the following:
#implementation MJSegmentedControl
- (void)layoutSubviews
{
[super layoutSubviews];
NSInteger cachedIndex = self.selectedSegmentIndex;
self.selectedSegmentIndex = 0;
self.selectedSegmentIndex = cachedIndex;
}
#end
I haven't had a need to use the appearance controls of iOS 5 yet but if all else fails you could add the resizable image as a child of the segmented control to cover up the ugliness. It's a hack, but it may work and will be relatively forwards-compatibile. Just be certain to set the autosizing masks appropriately.
I had the same issue and it really seems to be a bug. However I've found a solution (a workaround).
I've used XIB file with a controller. In XIB file segmented control was just placed and all of the customisations were done in -viewDidLoad method.
Then I've created a UIView subclass which represented entire view in the XIB. It made possible moving all view customisation code to the -awakeFromNib method of this UIView subclass. After moving this code the divider images were set properly.
As suggested by Fernando in this thread:
Customizing UISegmentedControl in iOS 5
You can try to dispatch your UISegmentedControl settings on the main queue via:
dispatch_async(dispatch_get_main_queue(),^{
// disable part of the segmented control
[self.eventScopeSegmentedControl setEnabled:NO forSegmentAtIndex:2];
});
I did this in viewDidLoad and it worked fine for a while but when my app is really busy at startup, this doesn't always work. I'm guessing there's a race condition that may still revert any settings you made when the appearance proxy goes to work.
I added another ugly hack to make this call in viewWillAppear (after the call to super:viewWillAppear) with a flag (set from viewWillLoad) to ensure this only runs once.
There is actually a pretty simple way to get this done. The current behavior is obviously a bug so this is not an ideal solution but simply a workaround that works beautifully. Namely, use an additional UIView as a "disabled visual cue".
The general steps:
Add a UIView as a sibling to the UISegmentedControl. Ensure the UIView is in front of the UISegmentedControl
Apply the desired color and a transparency to the UIView to match your app skin
Move the UIView to be exactly on top of the UISegmentedControl
Shape the UIView to have the exact size top of the UISegmentedControl
Apply a rounded corner to the UIView to mirror the exact shape of the UISegmentedControl
When the UISegmentedControl is supposed to be disabled, simply show the UIView and disable the user interaction on the UISegmentedControl.
When the UISegmentedControl is supposed to be enabled, simply hide the UIView and enable the user interaction on the UISegmentedControl.
In both cases do not change the UISegmentedControl.enabled property.
Note that it seems like a lot of steps but all of this can be coded in so to add support for disabling your custom UISegmentedControl becomes pretty much a 1 liner after you add this to a configure segmented control method.
Here is how my custom segmented control looks when applying this solution:
Enabled Segmented Control
"Disabled" Segmented Control
Here are some code snippets of interest:
Shape the UIView to match the UISegementedControl (load time configuration)
UISegmentedControl* segmentedControl = ...
//Segmented Control disabled visual cue view
UIView* view = ...
//Step #2
view.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6];
//Step #3 and #4
view.frame = segmentedControl.frame;
//Step #5
view.layer.cornerRadius = 5
view.clipsToBounds = YES;
//Ensure this is disabled by default
view.userInteractionEnabled = NO;
Enable/"Disable" UISegementedControl (runtime state change)
BOOL segmentedControlEnabled = ...
if(segmentedControlEnabled) {
segmentedControl.userInteractionEnabled = YES;
view.hidden = YES;
} else {
segmentedControl.userInteractionEnabled = NO;
view.hidden = NO;
}
That's it.
-

Turn off highlighting on UIBarButtonItem

I'm trying to use a UIBarButtonItem to put a title on my UIToolbar. I'm using the plain style and that looks fine, but I can't seem to get it to stop highlighting on touch. The Shows Touch When Highlighted option isn't available for the bar button items. Is there a quick and easy way to do this? I'm trying to do the building in interface builder so I can see what I'm doing. I'd prefer not to build the toolbar in the view did load every time.
The property responsible for this is accessible in the UIButton class:
myButton.showsTouchWhenHighlighted = NO;
You can access this (programmatically) in a UIBarButtonItem by assigning a UIButton to the bar button item's customView property, and configuring the button. You can do this in Interface Builder too: drag a UIButton onto a UIToolbar, and it will automatically embed it in a UIBarButtonItem for you - then look for the "Shows Touch On Highlight" checkbox under the button's settings.
Incidentally, I don't know how you're customising your buttons so feel free to ignore this, but if your button looks and behaves like a standard toolbar item then users will expect the glow effect.
I wanted a solution that could be used without any modification to my XIB structure.
The most obvious and simple one worked: subclass UIBarButtonItem:
UITitleBarButtonItem.h:
//
// UITitleBarButtonItem.m
// Created by Guillaume Cerquant - MacMation on 09/08/12.
//
/*
* A UIBarButtonItem that does not show any highlight on the touch
* Drag and drop a normal UIBarButtonItem in your xib and set its subclass to UITitleBarButtonItem
*/
#interface UITitleBarButtonItem : UIBarButtonItem
#end
UITitleBarButtonItem.m:
#import "UITitleBarButtonItem.h"
#implementation UITitleBarButtonItem
// Only caring about UITitleBarButtonItem set up in Interface Builder. Update this class if you need to instantiate it from code
- (void) awakeFromNib {
UIView *theView = [self valueForKey:#"view"];
if ([theView respondsToSelector:#selector(setUserInteractionEnabled:)]) {
theView.userInteractionEnabled = NO;
}
}
#end
Tested on iOS 5 and the one we aren't allowed to talk yet.
Alternative: Use a UIBarButtonItem in the plain style and additionally cover the toolbar in the appropriate area with a UIView that has a clear background. The view consumes the taps and hides them from the bar button item. Make sure you set the autoresizing mask correctly.
My solution was to set it to disabled, and adjust the titleAttributes for each UIControlState
let attributes: [NSAttributedStringKey: Any] = [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor.white
]
barButton.setTitleTextAttributes(attributes, for: .enabled)
barButton.setTitleTextAttributes(attributes, for: .disabled)
barButton.isEnabled = false

Resources