intrinsicContentSize – UIView のサイズを動的に変更する

UIView の intrinsicContentSize プロパティをオーバーライドし、invalidateIntrinsicContentSize を呼び出すことで、自身のサイズを動的に更新することができます。

class CustomView: UIView { 
    override var intrinsicContentSize: CGSize {
        return CGSize(width: ..., height: ...)
    }

    func updateSize() {
        // サイズ変更処理
        ...

        invalidateIntrinsicContentSize()
    }
}

UILabel に Padding をつける時などによく利用します。

class CustomLabel: UILabel {
    var padding: CGFloat = 0 {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override func drawTextInRect(rect: CGRect) {
        let newRect = CGRectInset(rect, padding, padding)
        super.drawTextInRect(newRect)
    }

    override func intrinsicContentSize() -> CGSize {
        let originalSize = super.intrinsicContentSize() // UILabel本来の文字列に応じて計算された大きさ
        return CGSizeMake(originalSize.width + padding * 2, originalSize.height + padding * 2)
    }
}

アニメーション付きで変更する場合は以下のように書きます。

UIView.animate(withDuration: 1, animations: {
    ...
    
    invalidateIntrinsicContentSize()
                
    self.superview?.setNeedsLayout()
    self.superview?.layoutIfNeeded()
})