Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode. Xib. Set a default font for text elements

Tags:

xcode

xib

How can i set a default font for text elements like UILabel, UITextView, UITextField in xib, when i create them? Now it is system 17.0.
enter image description here

like image 392
Nik Kov Avatar asked Feb 27 '26 08:02

Nik Kov


1 Answers

There is no way to do this directly in Interface Builder…but there is a way to accomplish this with some code involved.

You would need to look at the subviews recursively (since subviews can themselves have even more subviews) and add text elements as you come across them.

Here’s my work on that, verified working in Swift 3.0.2:

/// Recursively checks for UILabels, UITextFields, and UITextViews in a parent UIView and its subviews.
/// - parameter view: The UIView which may contain text elements for further, unified configuration.
/// - returns: A dictionary with UILabels, UITextFields, and UITextViews in their own arrays.
func textElementsInView(_ view: UIView) -> [String : Array<UIView>] {

    // Get the view's subviews.
    let subviews = view.subviews

    // Set up empty arrays for labels, text fields, and text views.
    var labels : [UILabel] = []
    var textFields : [UITextField] = []
    var textViews : [UITextView] = []

    // Check through the subviews in the given view.
    for subview in subviews {

        if subview.isKind(of: UILabel.classForCoder()) {

            // The subview is a label. Add it to the labels array.
            labels.append(subview as! UILabel)

        } else if subview.isKind(of: UITextField.classForCoder()) {

            // The subview is a text field. Add it to the textFields array.
            textFields.append(subview as! UITextField)

        } else if subview.isKind(of: UITextView.classForCoder()) {

            // The subview is a text view. Add it to the textViews array.
            textViews.append(subview as! UITextView)

        } else {

            // The subview isn't itself a text element...but it could have some in it!
            // Let's check it using this very function.
            let elements = textElementsInView(subview)

            // Add the labels...
            let subviewLabels = elements["labels"] as! [UILabel]
            labels.append(contentsOf: subviewLabels)

            // ...and the text fields...
            let subviewTextFields = elements["textFields"] as! [UITextField]
            textFields.append(contentsOf: subviewTextFields)

            // ...and the text views, to their respective arrays.
            let subviewTextViews = elements["textViews"] as! [UITextView]
            textViews.append(contentsOf: subviewTextViews)

        }
    }

    // Once we're done with all that, set up our elements dictionary and return it.
    let elements : [String : Array<UIView>] = ["labels" : labels, "textFields" : textFields, "textViews" : textViews]
    return elements
}

An example of applying styles universally, in Swift:

// Get the text elements in the given view.
let textElements = textElementsInView(view)

// Get the labels from the textElements dictionary.
let labels = textElements["labels"] as! [UILabel]

// Apply styles to any label in the labels array, all together.
for label in labels {
    label.font = UIFont.systemFont(ofSize: 24, weight: UIFontWeightBlack)
    label.textColor = UIColor.black
}

...and the method in Objective-C:

- (NSDictionary*)textElementsInView: (UIView*)view {

    // First, set up mutable arrays for our text element types.
    NSMutableArray *labels = [NSMutableArray new];
    NSMutableArray *textFields = [NSMutableArray new];
    NSMutableArray *textViews = [NSMutableArray new];

    // And get an array with our subviews.
    NSArray *subviews = [view subviews];

    // Loop through the subviews in the subviews NSArray
    for(UIView* subview in subviews) {
        if ([subview classForCoder] == [UILabel class]) {
            // If the subview is a UILabel, add it to the labels array.
            [labels addObject:subview];
        } else if ([subview classForCoder] == [UITextField class]) {
            // If the subview is a UITextField, add it to the textFields array.
            [textFields addObject:subview];
        } else if ([subview classForCoder] == [UITextView class]) {
            // If the subview is a UITextView, add it to the labels array.
            [textViews addObject:subview];
        } else {
            // Try running through this function for the view if none of the above matched.
            NSDictionary *subviewTextElements = [self textElementsInView:subview];

            // Get any labels in the subview and add them to the labels array.
            NSArray *subviewLabels = [subviewTextElements objectForKey:@"labels"];
            [labels addObjectsFromArray:subviewLabels];
            // Do the same for UITextFields...
            NSArray *subviewTextFields = [subviewTextElements objectForKey:@"textFields"];
            [labels addObjectsFromArray:subviewTextFields];
            // ...and UITextViews.
            NSArray *subviewTextViews = [subviewTextElements objectForKey:@"textViews"];
            [labels addObjectsFromArray:subviewTextViews];
        }
    }

    // After all that's done, create a dictionary and return it.
    NSDictionary *textElements = @{
                                   @"labels" : labels,
                                   @"textFields" : textFields,
                                   @"textViews": textViews
    };
    return textElements;
}

It's certainly not very pretty, but it's the only way I could think of to get the job done.

like image 76
Jonathan Thornton Avatar answered Mar 02 '26 03:03

Jonathan Thornton