【问题标题】:Custom UILabel View not updating it's frame in Interface Builder自定义 UILabel 视图未在 Interface Builder 中更新其框架
【发布时间】:2019-10-14 22:13:39
【问题描述】:

我正在尝试为 Font Awesome 创建一个 UILabel,目前它似乎运行良好。我遇到的问题是,当我更改 prepareForInterfaceBuilder() 中标签的字体大小时,它不会反映在 Interface Builder 中。

这是我的代码:

import Foundation
import UIKit

@IBDesignable
class FALabel : UILabel {

    @IBInspectable
    private var icon: String = ""

    @IBInspectable
    private var weight: NSInteger = 0

    /**
     * The type for the Font Awesome Label
     */
    enum FAType {
        case Brands
        case Light
        case Regular
        case Solid
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }

    /**
     * Prepare the view or the Interface Builder.
     */
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        setupView()
    }

    /**
     * Set up the view.
     */
    func setupView() {
        let type: FAType =  {
            switch self.weight {
            case 0:  return .Light
            case 2:  return .Solid
            case 3:  return .Brands
            default: return .Regular
            }
        }()

        setFontAwesomeIcon(faType: type, size: self.font.pointSize, icon: FAIcons.iconNamed(name: self.icon))
        self.sizeToFit()
        self.frame = CGRect(x: self.frame.minX, y:self.frame.minY, width:self.frame.width, height:self.frame.height)
        self.invalidateIntrinsicContentSize()
    }

    /**
     * Calculate the intrinsic content size.
     */
    override var intrinsicContentSize: CGSize {
        return CGSize(width: self.frame.width, height: self.frame.height)
    }

    /**
     * Set the Font Awesome Icon for the label.
     *
     * - parameter fatype: The type to set.
     * - parameter size:   The size for the font.
     * - parameter icon:   The icon to use.
     */
    func setFontAwesomeIcon(faType: FAType, size: CGFloat, icon:String) {
        if faType == .Regular {
            self.font = UIFont(name: "FontAwesome5Pro-Regular", size: size)
        } else if faType == .Solid {
            self.font = UIFont(name: "FontAwesome5Pro-Solid", size: size)
        } else if faType == .Light {
            self.font = UIFont(name: "FontAwesome5Pro-Light", size: size)
        } else if faType == .Brands {
            self.font = UIFont(name: "FontAwesome5Brands-Regular", size: size)
        }
        self.text = icon
    }
}

当我在 Interface Builder 中更改任何内容时,框架似乎保持相同的大小,但图标本身却像我想要的那样被绘制得更大。

我认为从prepareForInterfaceBuilder() 调用self.sizeToFit() 应该调整视图大小并更改那些15x18 尺寸,但似乎并非如此。

【问题讨论】:

    标签: ios swift interface-builder custom-view


    【解决方案1】:

    我认为任何尺寸相关的调整都应该放在layoutSubviews

    override func layoutSubviews() {
       super.layoutSubviews()
       setupView()
    }
    

    您可能会使用prepareForInterfaceBuilder 来填充一些样本数据,例如在 IB 中进行预览,但您不应该回忆您在 init 方法中所做的设置(例如 setupView())。

    您也可以省略我猜想的 init 方法并将所有内容简化为:

    import Foundation
    import UIKit
    
    @IBDesignable
    class FALabel : UILabel {
    
        @IBInspectable
        public var icon: String = "" { 
            didSet { setupView() } 
        }
    
        @IBInspectable
        public var weight: NSInteger = 0 { 
            didSet { setupView() } 
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
            setupView()
        }
    
        /**
         * The type for the Font Awesome Label
         */
        enum FAType {
            case Brands
            case Light
            case Regular
            case Solid
        }
    
        /**
         * Set up the view.
         */
        func setupView() {
            let type: FAType =  {
                switch self.weight {
                case 0:  return .Light
                case 2:  return .Solid
                case 3:  return .Brands
                default: return .Regular
                }
            }()
    
            setFontAwesomeIcon(faType: type, size: self.font.pointSize, icon: FAIcons.iconNamed(name: self.icon))
            self.sizeToFit()
            self.frame = CGRect(x: self.frame.minX, y:self.frame.minY, width:self.frame.width, height:self.frame.height)
            self.invalidateIntrinsicContentSize()
        }
    
        /**
         * Calculate the intrinsic content size.
         */
        override var intrinsicContentSize: CGSize {
            return CGSize(width: self.frame.width, height: self.frame.height)
        }
    
        /**
         * Set the Font Awesome Icon for the label.
         *
         * - parameter fatype: The type to set.
         * - parameter size:   The size for the font.
         * - parameter icon:   The icon to use.
         */
        func setFontAwesomeIcon(faType: FAType, size: CGFloat, icon:String) {
            if faType == .Regular {
                self.font = UIFont(name: "FontAwesome5Pro-Regular", size: size)
            } else if faType == .Solid {
                self.font = UIFont(name: "FontAwesome5Pro-Solid", size: size)
            } else if faType == .Light {
                self.font = UIFont(name: "FontAwesome5Pro-Light", size: size)
            } else if faType == .Brands {
                self.font = UIFont(name: "FontAwesome5Brands-Regular", size: size)
            }
            self.text = icon
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多