UIButton tap area got smaller on iOS 11 - objective-c

I notice the tap area for my UIButton got smaller since iOS 11. To confirm, I commented out the desired background color on its subviews and put purple color on the button itself.
iOS 10.0.3 (Button shown as desired)
iOS 11.1 (Tap area got smaller)
My code follows.
UIImage *ringImage = [UIImage imageNamed:#"ball20r"];
UIEdgeInsets insets = UIEdgeInsetsMake(10,10,10,10); //padding
UIImage *stretchableImage = [ringImage resizableImageWithCapInsets:insets];
UIImageView *imageView = [[UIImageView alloc]initWithImage:stretchableImage];
// imageView.backgroundColor = backgroundColor; //disabled for testing
imageView.frame = CGRectMake(0, 0, label.frame.size.width + 16.0, label.frame.size.height + 16.0);
[imageView addSubview:label];
label.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *viewsDictionary = #{#"label":label};
NSArray *constraint_H = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(8)-[label]-(8)-|"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(8)-[label]-(8)-|"
options:0
metrics:nil
views:viewsDictionary];
[imageView addConstraints:constraint_H];
[imageView addConstraints:constraint_V];
UIButton *calendarButton = [UIButton buttonWithType:UIButtonTypeCustom];
[calendarButton addTarget:self action:#selector(chooseACalendarToSave) forControlEvents:UIControlEventTouchUpInside];
calendarButton.frame = imageView.frame;
[calendarButton addSubview:imageView];
//added for testing only
calendarButton.backgroundColor = [UIColor purpleColor];
_calendarButton = [[UIBarButtonItem alloc]initWithCustomView:calendarButton];
How can I make the area for iOS just like iOS 10.0.3 and earlier?
Thanks for your help.

The answer is here.
iOS 11 UIBarButtonItem images not sizing
if (#available(iOS 9, *)) {
[cButton.widthAnchor constraintEqualToConstant: standardButtonSize.width].active = YES;
[cButton.heightAnchor constraintEqualToConstant: standardButtonSize.height].active = YES;
}
As soon as I inserted above code, the button started working as expected. Thank you.

Related

Content in Table cell of iOS 8 is not display

Everything works well in iOS 9.
But in iOS 8, the content is not displayed, only imageview is showed.
What i did is that I create a view and add label and UIImage to that view. Then that view is added to contentView of table Cell
create View
- (UIView *)getHeaderView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, HEADER_SECTION_HEIGHT)];
[view setBackgroundColor:[[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"Layer1Color"]]];
UILabel *taskName = [[UILabel alloc] initWithFrame:CGRectMake(5.0, SECTION_BREAK+3.0, view.frame.size.width-23.0, 20)];
[taskName setFont:[UIFont boldSystemFontOfSize:[[_themeComponent valueForKey:#"RegularFontSize"] intValue]]];
[taskName setText:combinedTask.taskDescription];
[taskName setTextColor: [[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"textPrimary"]]];
[view addSubview:taskName];
UIImageView *addressView = [[UIImageView alloc]initWithFrame:CGRectMake(5.0, SECTION_BREAK+28.0, 20, 20)];
addressView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png", #"Attr_Pin"]];
[view addSubview:addressView];
UILabel *address = [[UILabel alloc] initWithFrame:CGRectMake(35.0, SECTION_BREAK+23.0, view.frame.size.width-35.0, 30)];
[address setFont:[UIFont boldSystemFontOfSize:[[_themeComponent valueForKey:#"SmallFontSize"] intValue]]];
address.lineBreakMode = NSLineBreakByWordWrapping;
address.numberOfLines = 0;
[address setText:[NSString stringWithFormat:#"%#", unit]];
[address setTextColor: [[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"textPrimary"]]];
[view addSubview:address];
return view;
}
Add view to table cell
UIView *header= [self getHeaderView:tableView viewForHeaderInSection:section];
cell.taskIdLabel.hidden = YES;
[cell.contentView addSubview:header];
Anyone has any ideas? Thanks much for your help.
This is because iOS 9 Apple handle good autolayout than before.
Let add [cell layoutIfNeeded] before return cell.
Update
I have same problem before. Here is block of code that i use to solved my problem.
- (void) sizeHeaderToFit {
//call in viewLayoutSubView
UIView *myHeaderView = self.tableView.tableHeaderView;
[myHeaderView setNeedsLayout];
[myHeaderView layoutIfNeeded];
CGFloat height = [myHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
myHeaderView.frame = ({
CGRect headerFrame = myHeaderView.frame;
headerFrame.size.height = height;
headerFrame;
});
self.tableView.tableHeaderView = myHeaderView;
}
call it at viewDidLayoutSubView. Hope it helps bạn :))

UINavigationItem rightbarbuttonitem not displaying

As my title, I have went through several websites and failed to achieve the result. However, I managed to add an image on the navigation bar successfully. These are two problems I'm facing currently, both are under UINavigationBar section.
1. Unable to display the rightbarbutton
2. Unable to hide the back arrow "<"
MasterViewController.m
//Back Button
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"sidemenu.png"];
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
backBtn.frame = CGRectMake(0, 0, 54, 30);
//Rightbarbutton
UIButton *infoButton = (UIButton *) [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon_info.png"]];
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
self.navigationItem.rightBarButtonItem = infoButtonItem;
//Image (Working and displaying)
UIImage *image = [UIImage imageNamed: #"icon_image.png"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(245, 0, 30, 42)];
[imageView setImage:image];
[self.navigationController.navigationBar addSubview:imageView];
I think you should initialize you rightItem's content as an UIButton and not a cast from ImageView to UIButton... so the same procedure you are doing for the back item..
This is your UINavigationItem+AtAdditions.h file
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ATNavigationItemButtonSide) {
ATNavigationItemButtonSideRight,
ATNavigationItemButtonSideLeft
};
#interface UINavigationItem(ATAdditions)
// This method adds an image-only button to the requested size (right or left) of the current navigation item, the image can't be tapped
- (void)addColorfulImage:(NSString*)imageName toSide:(ATNavigationItemButtonSide)side;
#end
This is your UINavigationItem+AtAdditions.m file
#import "UINavigationItem+ATAdditions.h"
#implementation UINavigationItem(ATAdditions)
- (void)addColorfulImage:(NSString*)imageName toSide:(ATNavigationItemButtonSide)side {
// Create a button with the required image on it
UIImage *image = [UIImage imageNamed:imageName];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.bounds = CGRectMake(0, 0, image.size.width, image.size.height );
[button setImage:image forState:UIControlStateNormal];
// Stop the events (it's an image only)
button.userInteractionEnabled = NO;
// Add the button to the navigation item
if (side == ATNavigationItemButtonSideLeft) {
self.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
else if (side == ATNavigationItemButtonSideRight) {
self.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
}
}
#end
Later you can import the .h file and use it on the navigation item in your view controller.

How to make status bar translucent?

i need help in making status bar translucent. In some parts of app its working fine, and in other its not.
This is how status bar is coming if i show navugation bar.
this is how is showing when i remove the navigation bar.
I need to show the navigation bar but status bar should be translucent. The background image is pushed down with the navigation bar.I have set the background image programmatically making a base class.
-(void)addBackGroundImage{
self.backGroundImage=[[UIImageView alloc] init];
self.backGroundImage.translatesAutoresizingMaskIntoConstraints=NO;
[self.backGroundImage setImage:[UIImage imageNamed:#"background"]];
self.backGroundImage.contentMode=UIViewContentModeScaleAspectFill;
[self.view addSubview:self.backGroundImage];
[self.view sendSubviewToBack:self.backGroundImage];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[_backGroundImage]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backGroundImage)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(0)-[_backGroundImage]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backGroundImage)]];
AppDelegate *objAppDelegate=[[UIApplication sharedApplication] delegate];
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, 20)];
view.backgroundColor=[UIColor clearColor];
[view setAlpha:0.2];
}
-(void)updateBackgroundImage:(UIImage *)bgImage{
[self.backGroundImage setImage:bgImage];
}
It is actually what you need to completely remove default header background (statusBar + navigationBar) and set your own:
// ViewController.m
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.tintColor = [UIColor yourColor]; // Set your tint color
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.opaque = NO;
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 64)];
bgView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Your_Background_Image"]];
[self.view addSubview:bgView];

UISegmentedControl setImage: Bug in iOS7

I have a UISegmentedControl in my app. As of iOS7 GM, the images I use are not showing up when run on iOS7 devices. Anyone else having this problem?
Here's what it looks like in iOS6.1 and earlier
.
and here is what it looks like in iOS7
.
Here is the code:
self.theSegmentedControl.frame = CGRectMake(self.theSegmentedControl.frame.origin.x, self.theSegmentedControl.frame.origin.y, 320, 35);
[self.theSegmentedControl setBackgroundImage:[UIImage imageNamed:#"img_toggleInactive"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.theSegmentedControl setImage:[UIImage imageNamed:#"btn_onceActive"] forSegmentAtIndex:0];
[self.theSegmentedControl setImage:[UIImage imageNamed:#"btn_recurringInactive"] forSegmentAtIndex:1];
[self.theSegmentedControl setImage:[UIImage imageNamed:#"btn_scheduledInactive"] forSegmentAtIndex:2];
[self.theSegmentedControl setDividerImage:[UIImage imageNamed:#"separator"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Has anyone found a workaround to this?
Woohoo! Here's the workaround:
//Add clear color to mask any bits of a selection state that the object might show around the images
self.theSegmentedControl.tintColor = [UIColor clearColor];
UIImage *onceActive;
UIImage *recurringActive;
UIImage *scheduledActive;
UIImage *separator;
//Setting imageWithRenderingMode: to imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal for iOS7 is key
if ([UIImage instancesRespondToSelector:#selector(imageWithRenderingMode:)]) {
onceActive = [[UIImage imageNamed:#"btn_onceActive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
recurringActive = [[UIImage imageNamed:#"btn_recurringInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
scheduledActive = [[UIImage imageNamed:#"btn_scheduledInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
separator = [[UIImage imageNamed:#"separator"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
else {
onceActive = [UIImage imageNamed:#"btn_onceActive"];
recurringActive = [UIImage imageNamed:#"btn_recurringInactive"];
scheduledActive = [UIImage imageNamed:#"btn_scheduledInactive"];
separator = [UIImage imageNamed:#"separator"];
}
[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0];
[self.theSegmentedControl setImage:recurringActive forSegmentAtIndex:1];
[self.theSegmentedControl setImage:scheduledActive forSegmentAtIndex:2];
[self.theSegmentedControl setDividerImage:separator forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UPDATE for Xcode 6/iOS 8
Now you can do it in Interface builder
Just add the image file in the asset catalog and set its "render as" original image instead of default
Xcode 5
The new UISegmented control uses the tint color to tint the images using the template mode.
You will need to render these images as original and not templates.
As suggested in the comments do this:
UIImage* onceActive = [UIImage imageNamed:#"btn_onceActive"];
if (IOS_7_MACRO)
onceActive = [onceActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0];
Use this Code to set Image on Segment Control in iOS 7 with xCode 5.0
if ([UIImage instancesRespondToSelector:#selector(imageWithRenderingMode:)]) {
[segmentControl setImage:[[UIImage imageNamed:#"image.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forSegmentAtIndex:0];
}
else {
[segmentControl setImage:[UIImage imageNamed:#"image.png"] forSegmentAtIndex:0];
}
It could be useful to create a category:
#interface UISegmentedControl (UISegmentedControlAdditions)
-(void)setImageRenderingMode:(UIImageRenderingMode)renderingMode;
#end
#implementation UISegmentedControl (UISegmentedControlAdditions)
-(void)setImageRenderingMode:(UIImageRenderingMode)renderingMode {
for (int index=0; index < [self numberOfSegments]; index++) {
UIImage * image = [self imageForSegmentAtIndex:index];
[self setImage:[image imageWithRenderingMode:renderingMode] forSegmentAtIndex:index];
}
}
... and just call
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
[colorSegmentedControl setImageRenderingMode:UIImageRenderingModeAlwaysOriginal];

picture appears as white space in button

I downloaded from a free icon DB a thumb up icon, its size is too large for a button and it had white background.I decided to open it in pixelmator resized the icon and removed the background. when opening it with preview it looks great but when its set to be the button's image in xcode it appears as a white circle.
here is the icon after edit (30x30 png)
and this is how it looks on the button
what should I do to fix this?
edit/ upadte:
I tried #yunas code and it works in the navigation bar not for the toolbar (didn't even show the button).
Trying this code:
UIImage* image = [UIImage imageNamed:#"imageName"];
UIBarButtonItem *likeBtn = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:#selector(action_clicked:)];
NSArray* toolbarItems = [NSArray arrayWithObjects:likeBtn,nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
resulted again in a button with the white drawing
So I was wondering: Is it even possible to have colored buttons in the toolbar? maybe i'm trying the imposible...
edit/ upadte II - the solution: wrapping a UIButton inside a UIBarButtonItem
#interface StatusUIBarButtonItem : UIBarButtonItem
- (id) initWithStatus: (enum StatusEnum)p_statusEnum;
#end
#implementation StatusUIBarButtonItem
- (instancetype)initWithStatus:(enum StatusEnum)p_statusEnum
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[self getStatusImage] forState:UIControlStateNormal];
[button addTarget:self action:#selector(status_Clicked:) forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 20, 20)];
self = [super initWithCustomView:button];
if (self)
{
self.statusButton = button;
}
return self;
}
#end
then in the ViewController class:
-(void) viewDidLoad
{
StatusUIBarButtonItem* stausBtn = [[StatusUIBarButtonItem alloc] initWithStatus:self.status];
NSArray* toolbarItems = [NSArray arrayWithObjects: stausBtn, nil];
self.toolbarItems = toolbarItems;
self.navigationController.toolbarHidden = NO;
}
I hope this will help others that like me want colored images in the toolbar
UIImage *buttonImage = [UIImage imageNamed:#"imageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
button.adjustsImageWhenDisabled = NO;
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(action:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = customBarItem;