菜鸟教程小白 发表于 2022-12-13 16:04:36

ios - 如何使用带有变换的 AutoLayout


                                            <p><p>苹果文件说:</p>

<blockquote>
<p>In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout calculates a view’s alignment rectangle based on its untransformed frame.</p>
</blockquote>

<p>所以,如果我有一个名为 <strong><em><code>View1</code></em></strong> 的 View ,它通过使用 transform 属性进行缩放,并且 <strong><em><code> View2</code></em></strong> 想要与 <strong><code>View1</code></strong> 的边缘对齐。如何使用 <strong><code>AutoLayout</code></strong> 做到这一点?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>好问题。正如您所引用的,约束适用于 View 的原始未转换边界。</p>

<p>为了能够使您的其他 View 尊重转换后的边界,一种方法是在应用转换后计算约束常量的偏移量。下面是与您的情况类似的示例,但有一个顶部约束,而不是 <em>leading/trailing/align</em>。但基本上你也可以对其他情况应用相同的程序。</p>

<p>这暂时有效,请随时改进此答案。</p>

<hr/>

<p><strong> Storyboard设置:</strong></p>

<p> <a href="/image/nrHtO.jpg" rel="noreferrer noopener nofollow"><img src="/image/nrHtO.jpg" alt="Storyboard Setup"/></a> </p>

<p><strong>应用<code>(scaleX:3, scaleY:2.5)的变换后的输出</code>.</strong></p>

<p> <img src="/image/WSke9.png?raw=true" width="352" height="625"/> </p>

<hr/>

<p><strong>我们在下面的代码中做的是:</strong></p>

<ol>
<li>制作约束的<code>IBOutlet</code>。</li>
<li>将约束的原始常量存储到变量中。</li>
<li>在应用之前存储要缩放的 View 框架<strong></strong>。</li>
<li>应用转换。</li>
<li>在<strong></strong>变换后存储 View 框架。</li>
</ol>

<p><strong>注意:</strong>根据 Apple 文档,它说:</p>

<blockquote>
<p><strong>Warning</strong> <br/>
When the value of this property is anything other than the
identity transform, the value in the frame property is undefined and
should be ignored.</p>
</blockquote>

<p>但转换后的框架似乎在应用比例后立即可用。所以我们将它保存到一个变量中以备将来使用。如果您尝试访问其他地方的框架,您将无法获得正确的框架。因此,我们在应用转换后立即执行此步骤。</p>

<ol start="6">
<li>通过覆盖 ViewController 的 <code>updateViewConstraints</code> 方法,您有机会更新约束。现在我们只需将两帧底部位置的差值应用到 <code>IBOutlet</code> 的约束常量上。</li>
</ol>

<hr/>

<pre><code>import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var view1: UIView! //Dark gray view
    @IBOutlet weak var view2: UIView! //Light gray view

    @IBOutlet weak var topConstraint: NSLayoutConstraint!

    let transformScaleX:CGFloat = 3
    let transformScaleY:CGFloat = 2.5

    var rectBeforeTransform:CGRect = .zero
    var rectAfterTransform:CGRect = .zero

    var originalTopConstraintConstant:CGFloat = 0

    override func viewDidLoad() {
      super.viewDidLoad()

      //Store original constraint value
      self.originalTopConstraintConstant = self.topConstraint.constant
      //Store unaltered frame of the view
      self.rectBeforeTransform = view1.frame
      //Apply transform
      self.view1.transform = .init(scaleX: transformScaleX, y: transformScaleY)
      //Frame after transform.
      //NOTE: When a non-identity transform is applied to a view, its frame is undefined, so we would not get proper frame info. of the view anywhere other than after applying the tranform.
      self.rectAfterTransform = view1.frame
    }

    override func updateViewConstraints() {
      DispatchQueue.main.async {
            let constraintOffset = abs(self.rectAfterTransform.bottomY - self.rectBeforeTransform.bottomY)
            self.topConstraint.constant = self.originalTopConstraintConstant + constraintOffset
      }
      super.updateViewConstraints()
    }

}

extension CGRect {
    var bottomY:CGFloat {
      get {
            return self.height + self.origin.y
      }
    }
}
</code></pre>

<hr/>

<p><strong>PS:</strong>当前答案仅适用于顶部约束,我将尝试更新所有 <em>leading/trailing/top/bottom</em> 约束的答案,可能还有一个更优雅的解决方案。至于动画,不幸的是我无法提供一种方法。如果我找到一些会更新。谢谢。</p>

<hr/></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何使用带有变换的 AutoLayout,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/53111763/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/53111763/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何使用带有变换的 AutoLayout