Xcode. Xib. Установите шрифт по умолчанию для текстовых элементов

#xcode #xib

#xcode #xib

Вопрос:

Как я могу установить шрифт по умолчанию для текстовых элементов, таких как UILabel, UITextView, UITextField в xib, при их создании? Теперь это system 17.0.
введите описание изображения здесь

Ответ №1:

Нет способа сделать это непосредственно в Interface Builder … но есть способ сделать это с помощью некоторого кода.

Вам нужно будет рекурсивно просматривать вложенные представления (поскольку вложенные представления сами по себе могут содержать еще больше вложенных представлений) и добавлять текстовые элементы по мере их появления.

Вот моя работа над этим, проверенная работа в 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
}
  

Пример универсального применения стилей в 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
}
  

… и метод в 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;
}
  

Это, конечно, не очень красиво, но это единственный способ, который я мог придумать, чтобы выполнить работу.

Комментарии:

1. Напишите вариант для objective-C, и щедрость ваша 🙂

2. @NikKov Отредактирован методом Obj-C.

Ответ №2:

Существует другое возможное решение, но оно требует немного больше ручного труда, чем более «автоматизированное» решение выше.

Это подклассы UILabel, UITextField и т. Д. И Установка шрифта по умолчанию для этого класса в init , Затем выбор их соответствующих объектов в Interface Builder и настройка подклассов по мере необходимости.

Учитывая, что это не мое предпочтительное решение для этой ситуации, я не буду вдаваться в подробности, которые я сделал для другого ответа. Но если вам интересно это решение, вот полезная ссылка о подклассах UILabel из дней Swift 1. Я скажу, что с тех пор все немного изменилось, но вам должно быть довольно просто разобраться в этом самостоятельно.

Важное примечание: ни одно из этих решений для универсальной настройки стилей не появится в Interface Builder. Это настройки среды выполнения, поэтому вам просто нужно убедиться, что настройки установлены правильно при сборке.

Лично я бы рекомендовал просто установить их вручную по сравнению с любым из этих решений, если только у вас нет какой-либо динамической ситуации, требующей любого из этих параметров.