I have a storyboard with labels. The label's font is set to System 25.
I wanted to make the font size dynamic, and I set it by code now.
I set breakpoints, so I know that "25" is actually chosen in my code, but the font size still is smaller than when I set it in the storyboard designer.
Does anybody perhaps spot where I might have gone wrong or any caveats that I might have missed?
//set label font size
CGFloat nFontSize;
if (bIsIPad)
{
nFontSize=25.0;
}
else if (bIsIPhone_3GS_4_4s_Or_iPodTouch_3_4)
{
nFontSize=12.0;
}
else if (bIsIphone_5_Or_IPodTouch_5)
{
nFontSize=25.0;
}
UIFont *nFont = [UIFont fontWithName:#"System" size:nFontSize];
captionLabel0.font = nFont;
captionLabel1.font = nFont;
It seems that "fontWithName:#"System"" is not the same as "[UIFont systemFontOfSize:nFontSize];"
The storyboard property page seems to reflect "systemFontOfSize" when it displays the font "System".
When I chose "systemFontOfSize", the results were the same as in the storyboard.
You need to connect your label to outlet (storyboard).
And after that, you set the font size for this label.
Related
I have a macOS app that runs only in the macOS status bar. I changed the "Application is agent (UIElement)" property in the Info.plist to "YES":
<key>LSUIElement</key>
<true/>
I have a timer that prints out the appearance's name every 5 seconds like this:
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
let appearance = NSAppearance.currentDrawing()
print(appearance.name)
}
Problem
The name doesn't actually change when I toggle dark/light mode in system settings. It always prints the name of the appearance that was set when the application launched.
Is there a way to listen to system appearance changes?
Goal
My end goal is actually to draw an NSAttributedString to an NSImage, and use that NSImage as the NSStatusItem button's image.
let image: NSImage = // generate image
statusItem.button?.image = image
For the text in the attributed string I use UIColor.labelColor that is supposed to be based on the system appearance. However it seems to not respect the system appearance change.
When I start the application in Dark Mode and then switch to Light Mode:
When I start the application in Light Mode and then switch to Dark Mode:
Side note
The reason why I turn the NSAttributedString into an NSImage and don't use the NSAttributedString directly on the NSStatusItem button's attributedTitle is because it doesn't position correctly in the status bar.
The problem with drawing a NSAttributedString is, that NSAttributedString doesn't know how to render dynamic colors such as NSColor.labelColor. Thus, it doesn't react on appearance changes. You have to use a UI element.
Solution
I solved this problem by passing the NSAttributedString to a NSTextField and draw that into an NSImage. Works perfectly fine.
func updateStatusItemImage() {
// Use UI element: `NSTextField`
let attributedString: NSAttributedString = ...
let textField = NSTextField(labelWithAttributedString: attributedString)
textField.sizeToFit()
// Draw the `NSTextField` into an `NSImage`
let size = textField.frame.size
let image = NSImage(size: size)
image.lockFocus()
textField.draw(textField.bounds)
image.unlockFocus()
// Assign the drawn image to the button of the `NSStatusItem`
statusItem.button?.image = image
}
React on NSAppearance changes
In addition, since NSImage doesn't know about NSAppearance either I need to trigger a redraw on appearance changes by observing the effectiveAppearance property of the button of the NSStatusItem:
observation = statusItem.observe(\.button?.effectiveAppearance, options: []) { [weak self] _, _ in
// Redraw
self?.updateStatusItemImage()
}
It is very small that my icon Image in drop-down of combobox.
This problem is happening on Mac.
There was no problem on Windows.
I tried various methods, but I could not solve it.
Please tell me what is wrong.
Simplify:
QComboBox* combobox = new QComboBox(ui.parentWidget);
combobox->setStyleSheet("background-color: white;");
combobox->setIconSize(QSize(WIDTH, HEIGHT));
QString name = "testImage";
QString path = "~/testImage";
combobox->addItem(QIcon(path), "", name);
setStyleSheet() may be bad, but it couldn't be fixed by rewriting.
List of things to try:
enlarge the image itself
write stylesheet width, min-width, implicitWidth and fillmode
setSizePolicy()
setSizeAdjustPolicy()
setPalette()
setSize() for pixmap
El Capitan introduced San Francisco system font, which has proportional digits by default.
This makes numbers in table columns look jagged and hard to compare:
I'd like to enable fixed-width numbers option for the font, but keep using the default system font and keep backwards compatibility with earlier versions of OS X.
In Interface Builder selecting font > Font Panel > Typography > Monospaced Numbers does not affect the font (XIB file remains unchanged).
What's the right way to set monospaced numbers in OS X table view columns? (I suspect IB is unusable for this, so a programmatic solution is OK too).
Just use +[NSFont monospacedDigitSystemFontOfSize:weight:] when it's available. It's new in 10.11, but still not in the NSFont docs. It's in the headers and was discussed in the WWDC 2015 videos. So, something like:
if ([NSFont respondsToSelector:#selector(monospacedDigitSystemFontOfSize:weight:)])
textField.font = [NSFont monospacedDigitSystemFontOfSize:textField.font.pointSize weight:NSFontWeightRegular];
Here's a Swift extension that gives you a monospaced digits font with high legibility.
extension NSFont {
var legibleNumbersVariant: NSFont {
let features = [
[NSFontFeatureTypeIdentifierKey: kNumberSpacingType,
NSFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector],
[NSFontFeatureTypeIdentifierKey: kStylisticAlternativesType,
NSFontFeatureSelectorIdentifierKey: kStylisticAltSixOnSelector]
]
let descriptor = fontDescriptor.addingAttributes([NSFontFeatureSettingsAttribute: features])
return NSFont(descriptor: descriptor, size: pointSize) ?? self
}
}
Treat the following as pseudo-code, quickly done, not throughly tested, etc.
Given an NSFont which represents a font which has monospaced numbers as a feature the following method will produce another NSFont with that feature selected:
- (NSFont *) newMonospaceNumbersFont:(NSFont *)font
{
CTFontDescriptorRef origDesc = CTFontCopyFontDescriptor((__bridge CTFontRef)font);
CTFontDescriptorRef monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, (__bridge CFNumberRef)#(kNumberSpacingType), (__bridge CFNumberRef)#(kMonospacedNumbersSelector));
CFRelease(origDesc);
CTFontRef monoFont = CTFontCreateWithFontDescriptor(monoDesc, font.pointSize, NULL);
CFRelease(monoDesc);
return (__bridge_transfer NSFont *)monoFont;
}
You can use this, say, to take the current font of a UI element and convert it to one with monospace numbers.
HTH
Variant for Swift
Assuming res is the NSTextField with the number to display:
let origDesc = CTFontCopyFontDescriptor(res.font!)
let monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, kNumberSpacingType, kMonospacedNumbersSelector)
let monoFont = CTFontCreateWithFontDescriptor(monoDesc, res.font!.pointSize, nil)
res.font = monoFont
In my experience, the "font panel" functionality isn't well defined and I usually just ignore it whenever I'm messing with a XIB or Storyboard.
What should work is to go back to that "Font" attribute in the Text Field Cell attributes inspector and then select "User Fixed Pitch" from the Font drop down menu (the choice should automatically default to size 11).
If you bump the font size up a point, it'll magically switch to Monaco (the default fixed width font).
I'm trying to build a menubar application in swift. I want to set an image and text for the status item. Evidently NSStatusItem has deprecated setting a custom view since 10.10, which is fine, since I am able to set an image and text on the status item's button. However, I'm unable to set the imagePosition property for some reason and so the text and the image overlap.
This is my code:
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
let icon = NSImage(named: "statusIcon")
icon!.setTemplate(true) // best for dark mode
statusItem.button!.image = icon
statusItem.button!.imagePosition = ImageLeft
statusItem.button!.title = "Hello, world"
statusItem.menu = menu;
}
The problem is that Xcode gives me an error on this line:
statusItem.button!.imagePosition = ImageLeft
It says "Use of unresolved identifier 'ImageLeft'", but from what I can tell from the documentation (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSCell_Class/index.html#//apple_ref/c/tdef/NSCellImagePosition) that is the identifier I would want to use.
Can anyone help?
I figured it out. Evidently I have much to learn about Swift syntax.
This line allows it to work:
statusItem.button!.imagePosition = NSCellImagePosition.ImageLeft
I am working on a quiz game,it started as an iphone app,now it is fully working and i want to make it an universal app,but i can't find a way to set the font size to one value for all iphones and another for the ipad
I tried with the auto shrink menu in the interface builder,but it works only for labels,and if i do the same via code for uibutton the code doesn't work,this is the code i wrote inside viewdidload
ans2b.titleLabel?.numberOfLines = 1
ans2b.titleLabel?.adjustsFontSizeToFitWidth = true
ans2b.titleLabel?.minimumScaleFactor = 2
For the label i used interface builder and it works but the labels changes the font size every time the text inside it changes
How can i put a value for the font size for all iphones and a value for all ipads?Can i do it with interface builder or via code?
Maybe can i put a value in interface builder and some condition in viewdidload to change the size if the device is an ipad
Thanks
You can always check for device type.
if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
//label font size for iPad
}
else
{
//label font size for iPhones
}
We have a enum to define for device type check.
enum UIUserInterfaceIdiom : Int {
case Unspecified
case Phone // iPhone and iPod touch style UI
case Pad // iPad style UI
}