Get adjusted font size of label - ios

I have a header label which I am adjusting the font size of, to fit to the size of the label. I would like to store the value of that font size so I can set the font size of some buttons to it.
I have tried to just store the pointSize of the label, but that just gives me the unadjusted value, not the value that is actually in effect.
The reason for this is, that I want the size of all the text in labels and buttons to look good on different sized iPad screens. But I am struggling with keeping the size the same, across multiple elements.
class ViewController: UIViewController {
#IBOutlet weak var essenceButton: UIButton!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tribesButton: UIButton!
#IBOutlet weak var creaturesButton: UIButton!
#IBOutlet weak var monstersButton: UIButton!
#IBOutlet weak var musesButton: UIButton!
#IBOutlet weak var newsletterButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.titleLabel.adjustsFontSizeToFitWidth = true
let fontsize = self.titleLabel.font.pointSize
self.essenceButton.titleLabel?.font = essenceButton.titleLabel?.font.withSize(fontsize)
self.tribesButton.titleLabel?.font = tribesButton.titleLabel?.font.withSize(fontsize)
}
}

At viewDidLoad(), the view and its subviews (including the label) have not yet been laid out for the device's screen, so the label's font size has not changed.
You should be able to do this in viewWillLayoutSubviews():
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
view.layoutIfNeeded()
// Code to adjust font of the other UI items here
}

Related

iOS UIStackView .fill alignment inside UIScrollView not working

I have a stack view that is programmatically inserted inside a scroll view (which is working perfectly) but when I put the scroll view inside the view controller in a storyboard the alignment is .fill and the distribution of the component is not applicable through UI. Then I coded it as below but it still didn't work.
Below is the code of programmatic implementation:
class RegisterVC: UIViewController{
private let dataSource = ["Student","Academic Staff","Non academic Staff"]
#IBOutlet weak var userPicker: UIPickerView!
#IBOutlet weak var FirstName: UITextField!
#IBOutlet weak var LastName: UITextField!
#IBOutlet weak var EmailAddress: UITextField!
#IBOutlet weak var Password: UITextField!
//message popping validator labels
#IBOutlet weak var firstNameLabel: UILabel!
#IBOutlet weak var lastNameLabel: UILabel!
#IBOutlet weak var emailAddressLabel: UILabel!
#IBOutlet weak var passwordLabel: UILabel!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet var formStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView.translatesAutoresizingMaskIntoConstraints = false;
self.scrollView.addSubview(formStackView)
self.formStackView.translatesAutoresizingMaskIntoConstraints=false
self.formStackView.alignment = .fill
self.formStackView.distribution = .fillProportionally
self.formStackView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor,constant: 20).isActive=true
self.formStackView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor,constant: 20).isActive=true
self.formStackView.topAnchor.constraint(equalTo: self.scrollView.topAnchor,constant: 50).isActive=true
self.formStackView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor).isActive=true
//self.formStackView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive=true
userPicker.delegate=self
userPicker.dataSource=self
}
}
I'm a very basic beginner in iOS; I need your dire help, thank you.
That's an unusual way of designing in Storyboard... you can layout your stack view directly as a subview of your scroll view, and set up the constraints there (instead of via code).
But, I'll assume you have a reason for doing it that way, so...
You want to constrain the stack view's Top / Leading / Trailing / Bottom constraints to the scroll view's Content Layout Guide ... and then constrain its Width to the scroll view's Frame Layout Guide.
Try it like this:
class RegisterVC: UIViewController {
private let dataSource = ["Student","Academic Staff","Non academic Staff"]
#IBOutlet weak var userPicker: UIPickerView!
#IBOutlet weak var FirstName: UITextField!
#IBOutlet weak var LastName: UITextField!
#IBOutlet weak var EmailAddress: UITextField!
#IBOutlet weak var Password: UITextField!
//message popping validator labels
#IBOutlet weak var firstNameLabel: UILabel!
#IBOutlet weak var lastNameLabel: UILabel!
#IBOutlet weak var emailAddressLabel: UILabel!
#IBOutlet weak var passwordLabel: UILabel!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet var formStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
// not needed...
//scrollView.translatesAutoresizingMaskIntoConstraints = false;
// add form stack view to the scroll view
scrollView.addSubview(formStackView)
// because of the way this is designed in Storyboard,
// we need to set this to false
formStackView.translatesAutoresizingMaskIntoConstraints = false
// stack view alignment .fill
formStackView.alignment = .fill
// stack view distribution should be .fill
formStackView.distribution = .fill // .fillProportionally
// we want to constrain the stack view to the scroll view's Content Layout Guide
let svCLG = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
formStackView.leadingAnchor.constraint(equalTo: svCLG.leadingAnchor, constant: 20),
formStackView.trailingAnchor.constraint(equalTo: svCLG.trailingAnchor, constant: 20),
formStackView.topAnchor.constraint(equalTo: svCLG.topAnchor, constant: 50),
formStackView.bottomAnchor.constraint(equalTo: svCLG.bottomAnchor),
// constrain stack view Width to scroll view's Frame Layout Guide
// minus 40-pts, because we have 20-pts on each side
formStackView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -40),
])
}
}

How to make normal content look scrollable (like a UITableView)

I have a view controller with a few labels and switches inside of it. Is there any way to make the whole view look "scrollable" like how UITableViewCells look. Like even if there isn't enough content to need it to be scrollable I want that interactive gesture that UITableViewCells have. The whole point of this is to make all the pages on my app feel similar. Is there any way to add that same "scrolling" or "dynamic" feeling to the normal view?
Edit: A link to show what I mean
https://imgur.com/a/wJtfIKK
Here is the code where I connect the scroll view and I am making it "scrollable"
class ThemesViewController: UIViewController {
#IBOutlet weak var spacer: UIView!
#IBOutlet weak var overrideThemeDesc: UILabel!
#IBOutlet weak var overrideSystemTheme: UILabel!
#IBOutlet weak var overrideThemeToggle: UISwitch!
#IBOutlet weak var backgroundView: UIView!
#IBOutlet weak var lightButton: RadioButton!
#IBOutlet weak var darkButton: RadioButton!
#IBOutlet weak var lightText: UILabel!
#IBOutlet weak var darkText: UILabel!
#IBOutlet weak var appearanceLabel: UILabel!
#IBOutlet var interactiveView: UIScrollView!
let themeOverrideDefaults = UserDefaults.standard
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
interactiveView.alwaysBounceVertical = true
// Rest of My Code
}
And here is a picture of the storyboard with the scroll view selected (to show it has custom class UIScrollView): https://imgur.com/a/YCKPKpj
You can embed your view into a UIScrollView and then set
scrollView.alwaysBounceVertical = true
so that you get that scrolling effect even if the content is not large enough to be scrolled.
https://developer.apple.com/documentation/uikit/uiscrollview/1619383-alwaysbouncevertical

iOS: Global constraints for views in different view controllers

I have Same UILabel's in different viewcontrollers and I want to make the constraints of them global such that I should be able to edit them in one place and all viewcontrollers will adopt to it. To do that I have done something like this
#IBDesignable class TitleLabel: UILabel {
#IBOutlet weak var topConstraint: NSLayoutConstraint!
#IBOutlet weak var BottomConstraint: NSLayoutConstraint!
#IBOutlet weak var leftConstraint: NSLayoutConstraint!
#IBOutlet weak var rightConstraint: NSLayoutConstraint!
override func awakeFromNib() {
self.translatesAutoresizingMaskIntoConstraints = false
topConstraint.constant = 10
bottomConstraint.constant = 10
leftConstraint.constant = 20
rightConstraint.constant = 10
super.awakeFromNib()
}
}
So each of my label in different view controller is a TitleLabel and I connect its constraints in storyboard and change them in awakeFromNib()
Is there a better way then is approach for setting global constraints for same kind of label in different viewcontrollers?

Hidden parts of UI (hidden in code) still show up in simulator

I am using Xcode 8. In my code, I have certain items hidden, but when I launch the simulator to test, those same items show up. Is there something that I am missing?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var logoImg: UIImageView!
#IBOutlet weak var howManyTapsTxt: UITextField!
#IBOutlet weak var playBtn: UIButton!
#IBOutlet weak var tapBtn: UIButton!
#IBOutlet weak var tapsLbl: UILabel!
#IBAction func onPlayBtnPressed (sender: UIButton!) {
logoImg.isHidden = true
playBtn.isHidden = true
howManyTapsTxt.isHidden = true
tapBtn.isHidden = false
tapsLbl.isHidden = false
}
}
My code is above. The logo, howManyTapsTxt, and playBtn should be the only items shown when the simulator is launched. And when the playBtn is pressed, the tapsLbl and tapBtn should be the only items shown. But that is not the case. Any help/guidance is greatly appreciated. Thanks.
Your posted code makes no attempt to set the initial state of any of your views. The typical solution is to set the state in the viewDidLoad method.
override func viewDidLoad() {
super.viewDidLoad()
// Set the initial state of your views here
tapBtn.isHidden = true
tapsLbl.isHidden = true
}
The other option is to mark these views as hidden in Interface Builder.

Changing font size by using UISlider

I can't get this to work, and this code is not inside viewDidLoad()
#IBOutlet weak var label: UILabel!
#IBOutlet weak var slider: UISlider!
#IBAction func slider(sender: UISlider) {
let senderValue = CGFloat(sender.value)
label?.font = UIFont(name: (label?.font.fontName)!, size:senderValue * 20)
label?.sizeToFit()
}
If you could help in any way that would be great.
The code does not have to be inside viewDidLoad.
Do you use autoLayout to position your view?
This should work:
#IBOutlet weak var label: UILabel!
#IBOutlet weak var slider: UISlider!
#IBAction func sliderAction(sender: AnyObject) {
print("Slider value \(slider.value)")
self.label.font = UIFont.systemFontOfSize(CGFloat(slider.value * 20.0))
}
Check if:
UIFont object is initialised correctly.
Remove label?.sizeToFit. Normally, the label text is drawn with the font you specify in the font property.
Constraints are correctly set on the UILabel object.

Resources