2

この特定のシナリオでは、私は実際には非常に混乱しています。私は UINavigationBar をサブクラス化し、Apple の古いサンプル コードに注目し、sizeToFit が呼び出されずにオーバーライドされ、必要な高intrinsicContentSizelayoutSubviewsを計算することに気付きました。私が提供するカスタム ビューに基づいて高さを計算する場合は、すべてうまく機能します (systemLayoutSizeFittingSizeカスタム コンテンツ ビュー/titleView に基づいて動的に高さを計算するために使用します)。

奇妙な部分は、変更をアニメーション化しようとすると、 custom の変更をアニメーション化できますが、をtitleView介してintrinsicContentSizeをリロードするinvalidateIntrinsicContentSize()と、ビューフレームの変更がアニメーション化されないことです。スナップします。

サンプルコード:

let delta = destinationTextFieldContainerView.frame.minX - originTextFieldContainerView.frame.minX + originTextFieldContainerView.frame.height
textContainersSeparatorConstraint.constant = -delta
UIView.animateWithDuration(2, delay: 2, options: UIViewAnimationOptions.CurveEaseIn, animations: {
    self.customContainerNavigationBar.invalidateIntrinsicContentSize()
    self.customContainerNavigationBar.layoutIfNeeded()

    }) { (_) in
        self.customContainerNavigationBar.invalidateIntrinsicContentSize()
}

1 つの制約値の変更はアニメーション化されますが、残念ながら (navBars は自動レイアウトに依存していないため) フレームの更新に問題があるようです。固有のサイズを無効にする前に、フレームを直接更新しようとしましたが、成功しませんでした。また、高さの制約を試して、異なるタイミング オフセットを持つキー フレーム アニメーションにリストし、異なる時点でレイアウトを無効にしましたが、すべて成功しませんでした。どんな助けでも大歓迎です。

サイズ変更コードは次の場所にあります。

override func intrinsicContentSize() -> CGSize {
    var navigationBarSize = super.intrinsicContentSize()
    navigationBarSize.width = superview?.frame.width ?? 0

    guard let  titleView = navigationItem?.titleView else {
        return navigationBarSize
    }
    let fittingSize = CGSize(width: navigationBarSize.width, height: UILayoutFittingCompressedSize.height)
    let titleViewSize = titleView.systemLayoutSizeFittingSize(fittingSize)

    navigationBarSize.height = max(titleViewSize.height, 44)

    navigationBarSize.width = UIViewNoIntrinsicMetric
    return navigationBarSize
}


override func layoutSubviews() {

    super.layoutSubviews()

    guard let navigationItem = navigationItem, titleView = navigationItem.titleView else {
        return
    }
    var navigationBarSize = bounds.size
    navigationBarSize.width = superview?.frame.width ?? 0

    var fittingSize = CGSize(width: navigationBarSize.width, height: UILayoutFittingCompressedSize.height)

    if let leftBarButtonItem = navigationItem.leftBarButtonItem, leftButtonCustomView = leftBarButtonItem.customView {
        fittingSize.width -= leftButtonCustomView.frame.width + leftButtonCustomView.frame.origin.x + 22
    }

    let titleViewSize = titleView.systemLayoutSizeFittingSize(fittingSize, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityDefaultLow)

    titleView.frame = CGRect(origin: CGPoint(x: titleView.frame.origin.x, y: 0), size: titleViewSize)
    titleView.setNeedsLayout()
    titleView.layoutIfNeeded()

    if let leftBarButtonItem = navigationItem.leftBarButtonItem, leftButtonCustomView = leftBarButtonItem.customView {
        var customViewFrame = CGRect(origin: CGPoint.zero, size: navigationBarSize)

        let customViewSize = leftButtonCustomView.systemLayoutSizeFittingSize(customViewFrame.size, withHorizontalFittingPriority: UILayoutPriorityDefaultLow, verticalFittingPriority: UILayoutPriorityDefaultLow)
        customViewFrame.size = customViewSize
        leftButtonCustomView.frame = customViewFrame
        leftButtonCustomView.setNeedsLayout()
        leftButtonCustomView.layoutIfNeeded()
    }

    invalidateIntrinsicContentSize()

}
4

0 に答える 0