Make responsive label font size for iphone devices - ios

I am new to iOS Development.I am having problem with font size with phone screen size.For example Font size in iPhone 8 Plus looks fine but that text size is bigger in iPhone SE.I tried check Dynamic Type to Automatically Adjusts Font.And try to play with Autoshrink in StoryBoard.And i also tried to Add Font Variation in storyBoard.But I didnt get any good solution.Hope you understand my problem.Thanks in advance

Try this
class func dynamicFontSizeForIphone(fontSize : CGFloat) -> CGFloat
{
var current_Size : CGFloat = 0.0
current_Size = (UIScreen.main.bounds.width/320) //320*568 is my base
let FinalSize : CGFloat = fontSize * current_Size
return FinalSize
}
hope this work

You can change font size by using constraints.
1.take a label give its basic two constraint to satisfy. give one more constraint of equal.width to parent view. keep width as wide as your label text is.(a bit more than label text).
In attribute inspector there is a property name 'auto shrink' set it to 'minimum font size'
thats it.
Note: This will work fine if your Label text is constant. For changeable text there will be other approaches.

Related

UITextField: adjustsFontSizeToFitWidth behaviour/ issue

I have an issue with the usage of textField’s adjustsFontSizeToFitWidth. I have a textField with font size of 50 and a maximum width of 300 (This is a less than or equal to constraint). TextField is placed centre vertically and horizontally using auto layout. Now when I run the app, the text is being shrinked from the beginning itself. I know this may be because the system thinks the bounds of Texfield is not enough… but I gave the control to auto layout to figure that out and I assume it should work. Below is the snapshot… you can see the big placeholder and then suddenly the text shrinks… Any thoughts? Am I doing something wrong, I was trying to avoid manual calculation of width..
SourceCode Sample
Set leading/trailing space to text field like 15 pt from left safe area and 15 from Button so that it could automatically increase the font size. As now it shrinks the font to minimal 17 (which is set in storyboard) as the width is not enough.
Okay!! Finally I found a way, the idea was to check if the width is greater than the defined width limit... when the width is more I set adjustsFontSizeToFitWidth = true else set to false ... for some reason the solution didnt work when I clear the text... then I tried programatical approach and it started working .... dont know what was the difference... anyways I updated the source..... if there is a better solution let me know.
#IBAction func textChanged(_ txtField: UITextField) {
if txtField.frame.width >= (view.frame.width * widthMultiplier).rounded() {
txtField.adjustsFontSizeToFitWidth = true
} else {
txtField.adjustsFontSizeToFitWidth = false
}
}

Make UILabel auto-adjust font size to screen width, but not to text length

In a very simple single screen app, I have a single-line UILabel going from left edge to right edge of the screen.
The text of the label is dynamically updated at runtime. The length of the text varies, as it contains a number in the range 0...100, and I am neither using a monospaced font nor leading zeroes.
Here is an illustration:
|<--------- Screen width --------------->|
|<----- UILabel "Some value = 0" ------->|
|<----- UILabel "Some value = 50" ------>|
|<----- UILabel "Some value = 100" ----->|
I would like the label to always use the maximum width for any device (i.e. screen size). This can be achieved by using auto-layout, suitable leading and trailing constraints, a large font size and the "auto-shrink" property for the label.
The problem is, that this approach will make the font size also vary depending on the value displayed, which is not what I want. It should only vary with the width of the screen, but not with the length of the label text.
In the example above, a large font size would be used for the value 0, a medium one for 50 and a small one for 100. I want it to adjust to the worst-case (100) and use the resulting size for any text afterwards.
Is it possible to achieve this using Interface-Builder properties and auto-layout constraints only?
I can think of ways how to calculate sizes in code, but I think there must be an easier way.
You cannot express font size as a proportion of view width in interface builder but you can do it very easily in code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let textSize = Constant.baseFontSize * bounds.size.width / Constant.baseViewWidth
label.font = .systemFont(ofSize: textSize)
}

How to make text size relative to view in IOS?

In the XCode storyboard, I have set up my ViewController as a bunch of stackviews and everything is relative -- view dimensions are expressed as fractions of other view dimensions... lots of constraints, etc.
This is to make sure it looks decent on all IOS devices (phones and Ipads, anyway).
It does look acceptable in different aspect ratios, but I've noticed that the font size of my UILabels and TextViews are NOT changing -- not getting LARGER along with their containing views.
So, for example, if I switch from an iPhone to an iPad preview, a UILabel size may increase drastically and yet the text that it contains stays the same... so it's tiny text in a big box.
SO... the question is:
Is there a way to express font/text sizes as relative to the view that contains the text?
Something like this:
text.height = 0.7 * container.height
text.width = maintain aspect ratio with height
Thanks.
The same problem i had when i was designing an application for both iPhone and iPad and i tried this solution which is working fine but took a little efforts to manage. You need to create a custom label class which will inherits from UILabel class. There in your awakeFromNib function you can check the device and you can multiply whatever the font size with a ratio you feel ok for iPhone and iPad. You can also add checking for different iPhone sizes. If you wish to use different ratios for different label, make a IBDesignable property named dynamicRatio in your custom class and take that value to increase font. You can play around this. The effort is assigning the class to all your labels and setting properties which i use to do parallel during designing.
Below are the set of code which am using.
import UIKit
class MyLabel: UILabel {
#IBInspectable var autoFont: Bool = false
#IBInspectable var fontSize: CGFloat = 0
override open func awakeFromNib() {
super.awakeFromNib()
let baseHeight: CGFloat = (((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad)) ?1024.0:568.0)
if autoFont == true {
if (isDevice() == DEVICES.iPhoneX) {
let size: CGFloat = 667.0 * (fontSize / baseHeight)
self.font = UIFont(name: self.font!.fontName, size: size)
} else {
let size: CGFloat = UIScreen.main.bounds.size.height * (fontSize / baseHeight)
self.font = UIFont(name: self.font!.fontName, size: size)
}
}
}
}
Hope this idea helps.
Increase text font size of UILabels or UITextFields as you can, then set MinimumFontScale or MinimumFontSize attribute for them in "Attributes Inspector" tab, now font size increases as the UITextFields or UILabels size increases.
UILabel
UITextField

AdjustsFontSizeToFitWidth vs. SizeToFit

I'm using SizeToFit because I don't have to specify the Frame property to have an adaptive size of the UIButton/UILabel. In my case it's a button on a toolbar. Now I made the following observation:
If I use AdjustsFontSizeToFitWidth together with SizeToFit than the font size isn't adapted anymore. So I can
Specify a Frame and use AdjustsFontSizeToFitWidth
Use SizeToFit but don't have the adjustable font size anymore
Do you also have this problem? How do you circumvent this problem? How to let the intrinsic content size drive the frame size? Or do I have to set the Frame property? The advantage of Autolayout was to not define a frime size any more ...
I think I made an error in reasoning. SizeToFit defines the size after the content (content has already a fixed size). AdjustsFontSizeToFitWidth needs a frame in which it can change the font size. Both together doesn't work.
Here is a macro I've made to address this issue so that you can shrink font size to fit width AND call sizeToFit without the font size going back up post-shrink.
///Works like `adjustsFontSizeToFitWidth` but allows you to use `sizeToFit` and/or measure the new [adjusted] font size; one time adjustment, needs to be called again if `.text` changes.
#define shrinkFontSizeIfNeeded(__label) {\
UIFont *__currentFont = __label.font;\
CGFloat __originalFontSize = __currentFont.pointSize;\
CGSize __currentSize = [__label.text sizeWithAttributes:#{NSFontAttributeName : __currentFont}];\
while (__currentSize.width > __label.frame.size.width && __currentFont.pointSize > (__originalFontSize * __label.minimumScaleFactor)) {\
__currentFont = [__currentFont fontWithSize:__currentFont.pointSize - 1];\
__currentSize = [__label.text sizeWithAttributes:#{NSFontAttributeName : __currentFont}];\
}\
__label.font = __currentFont;\
}

VirtualTreeView node height based on icon font size

I am trying to set node height based on system icon font size.
My code so far:
LOGFONT lf;
ZeroMemory(&lf, sizeof(lf));
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
{
// This is a hack because font height itself doesn't give me correct node height - everything is too tight
int Height = VST->DefaultNodeHeight - abs(VST->Font->Height)+1;
VST->DefaultNodeHeight = abs(lf.lfHeight)+Height;
VST->Font->Name = lf.lfFaceName;
VST->Font->Height = lf.lfHeight;
}
The above works but I cannot get the DefaultNodeHeight right - it is not the same size as default used when font is fixed. Font height is good.
How can I retrieve the correct value from the system, or auto-size VirtualTreeView to use correct node height which would be the same as default but based on above code?
Default font height is -14, font size is 8 and node height is 18.
So in other words I need:
a) icon font size
b) appropriate DefaultNodeHeight, based on font size (in case if I use different font size, then DefaultNodeHeight is recalculated based on that particular size)

Resources