Question mark when tapping or holding font icons - ios

So I recently started some tinkering with my app to get it iOS 11 compatible. Thankfully most of it seems to be.
However I did notice, that in my toolbar if I tap or tap and hold an icon, which is supplied by a ttf file from fontello, I get a question mark box.
Example of icon:
menu = [[UIBarButtonItem alloc] initWithTitle:#"\ue811" style:UIBarButtonItemStylePlain target:self action:#selector(openMenu:)];
[menu setTitleTextAttributes:#{NSFontAttributeName:
[UIFont fontWithName:#"fontello"
size:23],
NSForegroundColorAttributeName:[[UIColor alloc] initWithWhite:1.f alpha:1.f]}
forState:UIControlStateNormal];
It works fine in the 10.3.1 simulator. Just iOS 11 seems to be goofed up. I've read about the fixes for devices, which means to update the OS, but the simulator is running 11.2, so in theory it should be fixed.
Is anybody else having this issue? Know of a fix?

Just add title text attributes for UIControlStateSelected also:
[menu setTitleTextAttributes:#{NSFontAttributeName:
[UIFont fontWithName:#"fontello"
size:23],
NSForegroundColorAttributeName:[UIColor greenColor]}
forState:UIControlStateSelected];

As mentioned in the comment, iOS 11 requires you to have a setting for normal state and selected/highlighted state. Below is what is working for me. Not ideal to have extra code depending on many buttons you have, but oh well.
[menu setTitleTextAttributes:#{NSFontAttributeName:[UIFont fontWithName:#"fontello"size:23],
NSForegroundColorAttributeName:[[UIColor alloc] initWithWhite:0.f alpha:1.f]}
forState:UIControlStateNormal];
[menu setTitleTextAttributes:#{NSFontAttributeName:[UIFont fontWithName:#"fontello"size:23],
NSForegroundColorAttributeName:[[UIColor alloc] initWithWhite:0.f alpha:0.5f]}
forState:UIControlStateHighlighted];

Related

UILabel appearance doesn't seem to do anything

It seems that [UILabel appearance] doesn't work anymore with latest iOS SDK.
Let's take this as an example:
- (void)viewDidLoad {
[super viewDidLoad];
[[UILabel appearance] setBackgroundColor:[UIColor redColor]];
[self.view addSubview:[[UILabel alloc] initWithFrame:CGRectMake(40, 80, 200, 100)]];
}
This code won't display the label with the red background.
If, on the other hand use this code:
- (void)viewDidLoad {
[super viewDidLoad];
[[UIImageView appearance] setBackgroundColor:[UIColor redColor]];
[self.view addSubview:[[UIImageView alloc] initWithFrame:CGRectMake(40, 80, 200, 100)]];
}
then the red area is visible.
Even if I change the property, i.e. change the font instead, or the text color (and display some text of course), no changes are visible.
On most S.O. questions regarding UILabel and appearance, although some people did have some problems, in general it seems to work, so I don't understand what I am doing wrong here.
The comments from #matt made me find the error. (Unfortunately he has retracted his answer so I can't give him the credits he deserves, if #matt you are listening, please give another answer in order to get the credits).
The reason why it was that, it is because it seems to be a Bug in iOS 12.
Under (beta) iOS 13 the behavior is as expected.

App layout messed up after updating to newest iOS

Background: My company has support contracts for an app to always make it work for the two latest iOS versions. Now instead of updating the deployment target and building it with the newest iOS version they just checked if the app that was built with iOS7 and a deployment target of iOS5(!!!) still worked on iPads with the newest iOS. And with some adjustments they somehow managed to make it work.
Now it's all coming back: The app won't work for iOS11, it didn't even build for arm64 till now. And I got the awesome task of making it work.
Making the app build with arm64 wasn't even that hard, just had to replace some libraries. But when building for iOS11 the layout of the app is messed up. One small example: On the login screen we got some buttons that will just cut their labels for no apparent reason. There is enough space for the text but it's still cutting off. Everything else on this view is the same as before.
The code for the buttons (Interface Builder hasn't been used in this app) looks completely fine to me, it's pretty much the same how I would do it today. So my guess is that there are some build settings or similar stuff I have to change for it to look like it should. Can anyone give me a hint here on what to do?
If you want to check out the code for the button, here you go. I can't give you all the code I have since it's company code but this should be no problem:
loginButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
loginButton.titleLabel.font = BUTTON_FONT_SMALL;
loginButton.frame = CGRectMake(x, passwordField.frame.origin.y + passwordField.frame.size.height + spacerHeight * 2, fieldLength, labelHeight);
loginButton.backgroundColor = [UIColor clearColor];
loginButton.titleLabel.textColor = [UIColor blackColor];
[loginButton setTitleColor:[UIColor colorFromString:#"47;72;127"] forState:UIControlStateNormal];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
[loginButton setBackgroundImage:buttonImageNormal forState:UIControlStateNormal];
[loginButton setBackgroundImage:buttonImageActive forState:UIControlStateSelected];
[loginButton setBackgroundImage:buttonImageActive forState:UIControlStateHighlighted];
loginButton.tag = 1;
[loginButton addTarget:self action:#selector(login_Tapped:) forControlEvents:UIControlEventTouchUpInside];
[[self view] addSubview:loginButton];

Why would this code work on iPhone 5, 4 and 4s but not 5s?

I have the below code for adding some UIBarButtons to my project. This works just fine on the following:
All on iOS 7.1
Simulator iPhone Retina 3.5 inch;
Simulator iPhone Retina 4 inch;
Simulator iPhone Retina 4 inch (64 bit)
Iphone 4
iPhone 4s
I don't have an iPhone 5 device to test though.
It doesn't work on a new iPhone 5s. Whats different?
Here is the code:
-(void)setupNavigationBar
{
self.saveSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.saveSearchButton setImage:[UIImage imageNamed:#"Save Search"] forState:UIControlStateNormal];
[self.saveSearchButton setImage:[UIImage imageNamed:#"Save Search Active"] forState:UIControlStateHighlighted|UIControlStateSelected];
[self.saveSearchButton addTarget:self action:#selector(saveSearchButtonpressed)forControlEvents:UIControlEventTouchUpInside];
[self.saveSearchButton setFrame:CGRectMake(0, 0, 23, 31)];
self.changeLayutButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.changeLayutButton setImage:[UIImage imageNamed:#"View List"] forState:UIControlStateNormal];
[self.changeLayutButton setImage:[UIImage imageNamed:#"View Grid"] forState:UIControlStateHighlighted|UIControlStateSelected];
[self.changeLayutButton addTarget:self action:#selector(changeViewLayoutButtonPressed)forControlEvents:UIControlEventTouchUpInside];
[self.changeLayutButton setFrame:CGRectMake(0, 0, 23, 31)];
self.sortByButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.sortByButton setImage:[UIImage imageNamed:#"Sort By"] forState:UIControlStateNormal];
[self.sortByButton setImage:[UIImage imageNamed:#"Sort By Active"] forState:UIControlStateHighlighted|UIControlStateSelected];
[self.sortByButton addTarget:self action:#selector(sortByButtonPressed)forControlEvents:UIControlEventTouchUpInside];
[self.sortByButton setFrame:CGRectMake(0, 0, 23, 31)];
UIBarButtonItem *fixedItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedItem.width = 20;
UIBarButtonItem *saveSearchButton = [[UIBarButtonItem alloc] initWithCustomView:self.saveSearchButton];
UIBarButtonItem *changeViewButton = [[UIBarButtonItem alloc] initWithCustomView:self.changeLayutButton];
UIBarButtonItem *sortByButton = [[UIBarButtonItem alloc] initWithCustomView:self.sortByButton];
NSArray *barbuttonitems = #[sortByButton, fixedItem, changeViewButton, fixedItem,saveSearchButton];
self.navigationItem.rightBarButtonItems = barbuttonitems;
self.lastLayoutUsed = [[NSUserDefaults standardUserDefaults]objectForKey:#"LastLayoutUsed"];
if ([self.lastLayoutUsed isEqualToString:#"GridLayout"]){
self.changeLayutButton.selected = YES;
[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(highlightButton:) userInfo:self.changeLayutButton repeats:NO];
}
}
I've stepped through the code and all the properties are not nil and have valid values. I've checked all images are the correct side, too.
How would this work on every device on simulator and not an actual iPhone 5S?
Also, since the two phones (iPhone 4S and 5S) have the exact same screen width and iOS version I am really puzzled?
The buttons don't show up at all. No compiler warning and no console errors.
UPDATE
Tested the above code on a iPhone 5 and it works just fine. This leads be to believe it must be something to do with the 64bit of the iPhone 5S?
UPDATE 2
Removed all the code from the method and changed it to a very simple button like this:
self.saveSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.saveSearchButton setTitle:#"Save" forState:UIControlStateNormal];
[self.saveSearchButton setTintColor:[UIColor blueColor]];
UIBarButtonItem *saveSearchButton = [[UIBarButtonItem alloc] initWithCustomView:self.saveSearchButton];
self.navigationItem.rightBarButtonItem = saveSearchButton;
This now doesn't work on any devices or simulators.
What am I doing wrong here?
Update 3 - Solution!
Right, so it was one simple thing that caused all this fuss. I declared my UIButtons as weak and not strong - I was under the impression that UI elements needed to be weak as they go off view so often?
I came to this answer with the help from the comments section.
This also does not explain why it works on iPhone 4S and iPhone 5 when declared as weak. It also worked on the 64 bit simulator declared as weak
Does this mean the 64bit simulator is to be used as a guide and actual testing must be done on the device as it seems the simulator is not accurate when it comes to UIKit testing?
I'd love to know more about this.
The problem was that [UIButton buttonWithType:UIButtonTypeCustom] doesn't leave an instance of the object as is stated in the Apple Docs. And the UIBarButton expects an instance of some sorts. https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html
The solution as is stated in the AppleDocs is using the alloc+init construction to make a button.
buttonWithType:
"This method is a convenience constructor for creating button objects
with specific configurations. If you subclass UIButton, this method
does not return an instance of your subclass. If you want to create an
instance of a specific subclass, you must alloc/init the button
directly."
#TotumusMaximus You have misunderstood what the documentation is saying. Note the first part:
If you subclass UIButton...
What this means is that if you try to do [MyAwesomeButton buttonWithType:UIButtonTypeCustom], the object that will be created will be a UIButton instance, NOT a MyAwesomeButton instance. In order to get a MyAwesomeButton instance, then you would need to do [[MyAwesomeButton alloc] init]. There are no button subclasses involved in the OP's problem, so this portion of the documentation does not apply here.
If your properties are weak, and you directly assign a newly created object to them, then by the rules of ARC they should immediately be deallocated and set to nil, since nothing else holds a strong reference to them. The fact that is was working on other devices / simulators was an accident of implementation.
There is no real need to use weak properties for UI elements now that views are not unloaded under memory pressure conditions any more. If you do still want to use weak properties, the correct pattern to use is to create a local (strong) reference, add it to a superview, and then assign to the property - at this point the button will have an owning reference (the superview) so will not be removed by ARC:
UIButton *button = [UIButton buttonWithType:whatever];
[self.view addSubview:button];
self.button = button;

Modify tintColor in UINavigationBar within MFMailComposeViewController

I'm trying to modify the tintColor in the UINavigationBar for the MFMailComposeViewController, but this doesn't seem to be working.
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], [MFMailComposeViewController class], nil] setTintColor:[UIColor blackColor]];
Before anyone quotes Apple saying that "The mail composition interface itself is not customizable and must not be modified by your application", I've previously submitted an app that is live in the App Store where the UINavigationBar had been modified in a similar manner, with no issues during the review process.
It works when I set the appearance for these classes across the entire app like this:
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor blackColor];
The issue is that I don't want these appearance settings to apply to all UINavigationBar/UIBarButtonItem instances.
Is my understanding of how to use appearanceWhenContainedIn: incorrect? Or is it something else?
Thanks for the help as always :)
This appears to be a bug in iOS 6.x, my Open Radar - http://openradar.me/radar?id=2984402
Apple has responded to me and it's a duplicate of a previously known bug (#12328070), so it should be fixed soon.
This code will work as expected in iOS 5.
In order to work around this, I suggest you manually apply what you want when you create the MFMailComposeViewController:
MFMailComposeViewController *mailComposerController = [[MFMailComposeViewController alloc] init];
[mailComposerController.navigationBar setTintColor:[UIColor redColor]];
I'll update my answer if I find anything else on the subject.

A UIButton above a UIPickerView

I have a UIPickerView which works correctly, now I want to add a button above it so that I can dismiss it.
and here is my code where I initiate a UIPickerView as well as its dismiss button:
- (UIPickerView *)creatPickerView {
UIPickerView *tempPickerView = [[[UIPickerView alloc]
initWithFrame:CGRectMake(kPickerViewX, kPickerViewY, kPickerViewWidth, kPickerViewHeight)] autorelease];
tempPickerView.showsSelectionIndicator = YES;
tempPickerView.delegate = self;
tempPickerView.dataSource = self;
UIButton *pickerButton = [[UIButton alloc] initWithFrame:CGRectMake(270, -32, 50, 32)];
[pickerButton setBackgroundImage:[UIImage imageNamed:#"hidePicker.png"]
forState:UIControlStateNormal];
[pickerButton addTarget:self action:#selector(hidePicker)
forControlEvents:UIControlEventTouchUpInside];
[tempPickerView addSubview:pickerButton];
[pickerButton release];
[self.view addSubview:tempPickerView];
return tempPickerView;
}
and it works well on my iPhone 4.3 Simulator, like this:
apparently there is a button on the upper right of the pickerView,
problem is, when I run the app in my device - a 5.0.1 iPhone4 and a 4.2.1 iTouch, the button is missed like it has never been added to the pickerView.
Can anyone help me with this?
Thanks a lot and a lot!
I found the reason, it seems the png has some problem,
after I change another png, it comes up in the screen!
but the real problem is that I place the button outside of the pickerView which results in the button's untouchableness.
But anyway the pickure is only a small problem.

Resources