UIButton not work in Landscape mode - ios

After rotation of iPad in my simulator i found a strange bug - my UIButton have visible title, it property enables is YES, but, its not work. I tried to set background colour of button to black, and found that after rotation it vanish. Please take a look at portrait mode (all work):
And landscape mode (not work):
This is how i create button (i doubt that it help though, because its pretty mundane):
self.readNextButton = [UIButton new];
self.readNextButton.backgroundColor = [UIColor blackColor];
// self.readNextButton.titleLabel.adjustsFontSizeToFitWidth = YES;
[self.readNextButton setTitleColor:[UIColor colorWithHexString:#"#60aabf"] forState:UIControlStateNormal];
self.readNextButton.titleLabel.lineBreakMode = NSLineBreakByClipping;
self.readNextButton.titleLabel.font = [UIFont fontWithName:#"Times New Roman" size:14];
[self.readNextButton setTitle:#"Читать дальше" forState:UIControlStateNormal];
[self.view addSubview:self.readNextButton];
Also, i want to notice that this bug appears even when i'm not rotating anything, but simply load app in landscape mode. And also, ENABLED property of button is 1 (mean YES), when i log it..
Button frame:
[self.readNextButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.containerForNewsText.mas_right).with.offset(-10.834);
make.bottom.equalTo(self.containerForNewsText.mas_bottom).with.offset(-10.834);
make.top.equalTo(self.truncatedNewsText.mas_bottom).with.offset(20);
}];
It is in a method 'createLandscapeConstraints', that called in end of viewDidLoad.

Related

Keep a hardware (bluetooth) keyboard from overriding an inputView in iOS 8

I have a UITextField that uses a custom UIPickerView in its inputView to restrict the user to a few options, functioning analogous to a dropdown list. When used with a hardware keyboard connected via bluetooth, the hardware keyboard overrides (and hides) my inputView. The associated inputAccessoryView remains, however. When press the "keyboard" button on my hardware keyboard (which would normally display the default on-screen keyboard for a vanilla UITextField), everything works as expected. (By which I mean my inputView is visible again.) In prior version of iOS (i.e. 7 and below), the inputView was always visible when called.
I have temporarily solved the problem by setting the UITextField's UIKeyboardType from UIKeyboardTypeDefault to UIKeyboardTypeTwitter, but this will only work while the hardware keyboard is not recognized as the default for that particular UIKeyboardType. Code is pickerTextField.keyboardType = UIKeyboardTypeTwitter; (See about 2/3 of the way into the code below.) Upon further testing, this partial solution isn't nearly as useful as it seems.
How can I correctly display my inputView in all situations while using a hardware keyboard?
Relevant code snippet:
-(int)setUpPickerWheelAtXLoc:(int)xLoc andYLoc:(int)yLoc {
int qwidth = width - (xLoc - FORMBORDERLEFT);
// Set up inputView (pickerView) to replace the keyboard
self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(xLoc, yLoc, qwidth, height)];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
self.pickerTextField = [[UITextField alloc] initWithFrame:CGRectMake(xLoc, yLoc, qwidth, 32)];
self.pickerTextField.delegate = self;
pickerTextField.borderStyle = UITextBorderStyleRoundedRect;
pickerTextField.layer.borderWidth = 0.3f;
pickerTextField.layer.borderColor = [[UIColor blackColor] CGColor];
pickerTextField.textColor = [UIColor blackColor];
pickerTextField.font = [UIFont systemFontOfSize:XXLARGEFONTSIZE];
pickerTextField.placeholder = #"Tap to choose from list...";
// Add pickerView as inputView
pickerTextField.inputView = self.pickerView;
pickerTextField.keyboardType = UIKeyboardTypeTwitter; // Suggested temporary solution
// Setup inputAccessoryView (Done button)
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[doneButton addTarget:self action:#selector(pickerDoneButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[doneButton setTitle:#"Done" forState:UIControlStateNormal];
doneButton.titleLabel.font = [UIFont systemFontOfSize:XXLARGEFONTSIZE];
doneButton.frame = CGRectMake(0,0,100,44);
[doneButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
doneButton.contentEdgeInsets = UIEdgeInsetsMake(0,0,0,20);
doneButton.backgroundColor = [UIColor lightGrayColor];
pickerTextField.inputAccessoryView = doneButton;
return xLoc + qwidth;
}
Additional Info: After checking a few other places, I have confirmed that this is happening in at least one Apple product as well. (In the "Create New Apple ID" app/page on an iPhone 6 in 8.0.2. See the Date of Birth pickerviews for Month and Day.)
The issue was fixed by Apple in the iOS 8.1 update.

Popover Control Background Color Odd Behavior

So in my app I have a popover control with an embedded navigation control. In different parts of the navigation stack, I want the popover to be different colors depending on where the user is. The weird thing is sometimes setting the popover background color makes this terrible looking box around it, sometimes it doesn't. It looks like this:
This is the look I am trying to get:
It seems if I change the background color before displaying the popover it seems to work and transition correctly, but if I don't set the popover color before showing it, then change it after it has been shown it has the box effect. I've also noticed other cases where it seems to happen randomly, but I can't really explain what is causing it (my real app is much more complex than this demo). Here is the relevant code:
- (IBAction)buttonPressed:(id)sender {
UIViewController *vc = [[UIViewController alloc] init];
UIButton *b = [[UIButton alloc] init];
[b addTarget:self action:#selector(innerButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[b setTitle:#"Button" forState:UIControlStateNormal];
[b setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[b setFrame:CGRectMake(0,0,100,100)];
[vc.view addSubview:b];
_innerNav = [[UINavigationController alloc] initWithRootViewController:vc];
_popOver = [[UIPopoverController alloc] initWithContentViewController:_innerNav];
//If this line is here, everything works fine
_popOver.backgroundColor = [UIColor yellowColor];
[_popOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
//If this line is here (and the above line is commented out), the transition will look wrong
//_popOver.backgroundColor = [UIColor yellowColor];
}
-(void)innerButtonPressed {
_controller = [[UIViewController alloc] init];
UIButton *b = [[UIButton alloc] init];
[b addTarget:self action:#selector(test) forControlEvents:UIControlEventTouchUpInside];
[b setTitle:#"Make Purple" forState:UIControlStateNormal];
[b setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[b setFrame:CGRectMake(0,0,200,200)];
[_controller.view addSubview:b];
[_popOver setBackgroundColor:[UIColor orangeColor]];
[_innerNav pushViewController:_controller animated:YES];
}
-(void)test{
_popOver.backgroundColor = [UIColor purpleColor];
}
Any idea what is causing this issue? And what steps to safely update the background color of a popover without ever getting into this state? I have a full project demonstrating the problem, I thought you could attach projects to questions but apparently you cannot. If someone wants it I can probably host it somewhere.
After looking at your sample project, Apple's "Popover Controllers in iOS" sample project, perusing Apple's Documentation, and trying a few different things I have come to the following observations:
The UIPopoverController only exhibits this odd behavior when it is presented without a valid value for the backgroundColor property. From this I am guessing that since UIPopoverController's backgroundColor property is nil by default it must use different drawing code than when the backgroundColor property is valid.
Triggering some sort of redraw (e.x. Setting popoverContentSize) will get the colored box overlay to go away (it looks like it clips a color layer).
Conclusion: For the time being I would set a backgroundColor prior to the UIPopoverController being presented and then update it as needed. If this is not an option try updating the UIPopoverController such that it redraws (As a note: I was not able to get this to look good and it seems hacky). Lastly, I would report it as a bug to apple.
I hope this helps.
UIPopoverController is now deprecated. I found a similar issue when updating it to use the new popoverPresentationController. In the past I was able to set the backgroundColor of UIPopoverController before presenting. The popover presentation controller also has a backgroundColor property but didn't work like it did before where I could assign it before presentation. To get it to work I had to assign it after it starts presenting for some reason:
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
[[self presentViewController:contentViewController animated:YES completion:^{
// completion code
}];
contentViewController.popoverPresentationController.backgroundColor = [UIColor orangeColor];
For your particular scenario where you are changing the background color after presentation is finished I don't think you'd be able to do that by just changing the popoverPresentationController's backgroundColor. The only solution I can think of is to dismiss and re-present the popover without animating:
[self dismissViewControllerAnimated:NO completion:^{
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
[[self presentViewController:contentViewController animated:NO completion:^{
// completion code
}];
contentViewController.popoverPresentationController.backgroundColor = [UIColor purpleColor];
}];

UISlider track image disappears when returning from a specific view

Image 1
Image 2
Image 3
1st image is the settings screen and everything behaves normally
upon the first loading of this screen.
2nd image is the policy
screen which is pushed from the settings screen.
3rd image upon returning from the policy screen back to the settings screen shows the UI Slider now doesn't show the track image. The behavior still works normally, but the track is just gone. It's a very mysterious bug to me. If I go to another screen in the app and then hit settings it works fine again, but when I come from the policy screen the track image is gone.
I am using the default UISlider. I am using xib files for the different screens.
When the Policy Button is clicked...
EditorialPolicyViewController *policyView;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
policyView = [[EditorialPolicyViewController alloc]initWithNibName:#"EditorialPolicyViewController_iPad" bundle:nil];
}
else
{
policyView = [[EditorialPolicyViewController alloc]initWithNibName:#"EditorialPolicyViewController_iPhone" bundle:nil];
}
[self.navigationController pushViewController:policyView animated:YES];
ViewDidLoad - setting up the uislider
NSString *textSize = [[NSUserDefaults standardUserDefaults] valueForKey:#"Text Size"];
float textSizeFloat = [textSize floatValue];
self.textSizeSlider.value = textSizeFloat;
[self.textSizeSlider setMaximumValue:16.0];
[self.textSizeSlider setMinimumValue:11.0];
Let me know if you have any other questions. I am out of ideas on how to solve this bug.
UPDATE
Found that the code below was "theming" the slider but when I removed it, it worked fine. What is a way i can keep the theme color and not get it to disappear?
[[UISlider appearance] setThumbTintColor:[UIColor colorWithRed:0/255.0f green:75/255.0f blue:152/255.0f alpha:1.0f]];
[[UISlider appearance] setMinimumTrackTintColor:[UIColor colorWithRed:164/255.0f green:75.0f blue:25/255.0f alpha:1.0f]];
[[UISlider appearance] setMaximumTrackTintColor:[UIColor colorWithRed:204/255.0f green:204/255.0f blue:204/255.0f alpha:1.0f]];
This is the well known bug in SetMaximumTrackTintColor.
Remove this line:
[[UISlider appearance] setMaximumTrackTintColor:[UIColor colorWithRed:204/255.0f green:204/255.0f blue:204/255.0f alpha:1.0f]];
and your app will work fine.
It is correct that this is a known bug. But have found a way to work around it so that you can still keep your theming:
[[UISlider appearance] setMaximumTrackTintColor:[UIColor colorWithRed:204/255.0f green:204/255.0f blue:204/255.0f alpha:1.0f]];
In UIViewController's where I use a slider, I set the maximumTrackTintColor in the viewDidLoad: method
- (void)viewDidLoad
{
[super viewDidLoad];
_slider.maximumTrackTintColor = [UISlider appearance].maximumTrackTintColor;
}
This works for me, so I wanted to share!
you can move the appearance changes into the viewDidLoad: function.
this way the appearance changes will only happened once.
- (void)viewDidLoad
{
// Appearance changes here
}
it works for me

AutoResizing a button based on title text content

So I have a strange issue which could be a bug or me being stupid.
I have a button in a cell. The cell shows the logged in users facebook friends. If they are already a user of the app it shows the button as Play, else it shows Invite Me...
UIButton *playButton = (UIButton *)[cell.contentView viewWithTag:30];
playButton.backgroundColor = [UIColor clearColor];
[playButton setBackgroundImage:[[UIImage imageNamed:#"fbCell_Invite_30h"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 5, 15, 5)] forState:UIControlStateNormal];
playButton.titleLabel.text = #"Invite me";
if ([self.fbFriendsUsingApp containsObject:[friend valueForKey:#"id"]]) {
playButton.titleLabel.text = #"Play";
}
This all works fine and not an issue. However, when the button text is invite me it shows as this:
In storyboard interface builder the button is setup like this:
What is strange is that if I click the middle arrow <------> to make the width stretch, the title text stops working and they all show 'Play' ???
Try setting the text of the button using
[playButton setTitle:#"Invite Me" forState:UIControlStateNormal];
instead of
playButton.titleLabel.text = #"Invite Me;
I've found that if I don't use the first approach above the changes to the button text don't show up.
You can find the size of the NSString that you are setting as the button label and then resize the button accordingly:
CGSize labelSize = [labelString sizeWithFont:[UIFont systemFontOfSize:12]];
[button setFrame:CGRectMake(10,0,labelSize.width, labelSize.height)];
You will probably want to add a little to the CGSize as padding, but play with it and find the result you desire.

How to change the font size of the text on a UISegmentedControl?

Following is the code for initializing my UISegmentedControl.
- (void)initializeToolButtons
{
NSArray *buttonTitles = [NSArray arrayWithObjects:#"ANNEXET", #"HOVET", #"GLOBEN", "ALL", nil];
toolbuttons = [[UISegmentedControl alloc] initWithItems:buttonTitles];
toolbuttons.segmentedControlStyle = UISegmentedControlStyleBar;
toolbuttons.tintColor = [UIColor darkGrayColor];
toolbuttons.backgroundColor = [UIColor blackColor];
toolbuttons.frame = CGRectMake(0, 0, 320, 30);
[toolbuttons addTarget:self action:#selector(toolButtonsAction) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:toolbuttons];
}
How can I reduce the font size for each item on the UISegmentedControl?
Note: toolButtons has already been declared globally.
Very simple:
UIFont *Boldfont = [UIFont boldSystemFontOfSize:16.0f];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:Boldfont forKey:UITextAttributeFont];
[segment setTitleTextAttributes:attributes forState:UIControlStateNormal];
Consider re-designing your interface or use the "tab" style which has a smaller font. Messing with unexposed properties might get your app rejected or break your app if they change something under the hood.
For example the code sample given doesn't work. When you tap on a segment the font for that segment gets reset to its normal size. Anything unpredictable can happen or change in your app if you do things that deviate from the normal useage of these things. So if you want an app that will continue working in following OS updates stick with the standard stuff, or make your own controls with UIButtons and rectangular background images. A hack might work now, but its not to say it will in the future.

Resources