【问题标题】:Xcode. Xib. Set a default font for text elementsXcode。西布。为文本元素设置默认字体
【发布时间】:2016-10-11 09:05:31
【问题描述】:

当我创建它们时,如何为 xib 中的 UILabel、UITextView、UITextField 等文本元素设置默认字体?现在是系统17.0。

【问题讨论】:

    标签: xcode xib


    【解决方案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;
    }
    

    这当然不是很漂亮,但这是我能想到的完成工作的唯一方法。

    【讨论】:

    • 为objective-C写一个变种,赏金是你的:)
    • @NikKov 使用 Obj-C 方法编辑。
    【解决方案2】:

    还有另一种可能的解决方案,但它比上述更“自动化”的解决方案需要更多的体力劳动。

    即继承UILabel、UITextField等,并在init中为该类设置默认字体,然后在Interface Builder中选择它们各自的对象并根据需要设置子类。

    鉴于这不是我对这种情况的首选解决方案,我不会详细介绍我为其他答案所做的详细说明。但是,如果您对这个解决方案感到好奇,here's a helpful link 关于子类化 UILabel 从 Swift 1 天开始。我会说从那以后事情发生了一些变化,但是您自己应该很容易弄清楚。

    重要提示:这些用于通用设置样式的解决方案都不会出现在 Interface Builder 中。这些是运行时设置,因此您只需确保在构建时正确设置了这些设置。

    就个人而言,我建议仅手动设置它们而不是这些解决方案中的任何一个,除非您有一些需要这些选项中的任何一个的动态情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2016-10-29
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多