菜鸟教程小白 发表于 2022-12-13 08:06:11

ios - 不是从中心缩放 UIView,而是使用 CATransform3DScale 从右下角缩放


                                            <p><p>我想根据滚动缩放(缩小)个人资料图片。但是,主要的是,我不想从中心点而是从右下角缩放它。意思是,右下角应该是固定的,图像应该从左上边缘收缩,如图所示:</p>

<pre><code>—————————————————
|               |
|    ———————————-   
|    |          |
|    |          |
|    |   —————|
|    |   |    |
|    |   |    |
—————————————————
</code></pre>

<p>这就是我正在做的。头像命名为<code>imgVwProfilePic</code>:</p>

<pre><code>- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offset = scrollView.contentOffset.y;
    CATransform3D avatarTransform = CATransform3DIdentity;
    CATransform3D headerTransform = CATransform3DIdentity;

    viewHeader.alpha = 1.0;

    // PULL DOWN -----------------

    if(offset &lt; 0)
    {
      CGFloat headerScaleFactor = -(offset) / CGRectGetHeight(viewHeader.bounds);
      int headerSizevariation = ((CGRectGetHeight(viewHeader.bounds) * (1.0 + headerScaleFactor)) - CGRectGetHeight(viewHeader.bounds))/2.0;
      headerTransform = CATransform3DTranslate(headerTransform, 0, headerSizevariation, 0);
      headerTransform = CATransform3DScale(headerTransform, 1.0 + headerScaleFactor, 1.0 + headerScaleFactor, 0);

      viewHeader.layer.transform = headerTransform;
    }

    // SCROLL UP/DOWN ------------

    else
    {
      CGFloat offset_HeaderStop = viewHeader.frame.size.height;
      headerTransform = CATransform3DTranslate(headerTransform, 0, MAX(-offset_HeaderStop, -offset), 0);

      float avatarScaleFactor = (MIN(offset_HeaderStop, offset)) / CGRectGetHeight(imgVwProfilePic.bounds) / 3.8; //1.4// Slow down the animation
      float avatarSizeVariation = ((CGRectGetHeight(imgVwProfilePic.bounds) * (1.0 + avatarScaleFactor)) - CGRectGetHeight(imgVwProfilePic.bounds)) / 2.0;

      avatarTransform = CATransform3DTranslate(avatarTransform, 0, avatarSizeVariation, 0);
      avatarTransform = CATransform3DScale(avatarTransform, 1.0 - avatarScaleFactor, 1.0 - avatarScaleFactor, 0);

      if(offset &lt;= offset_HeaderStop){
            if(imgVwProfilePic.layer.zPosition &lt; viewHeader.layer.zPosition){
                viewHeader.layer.zPosition = 0;
            }
      }

      else {
            if (imgVwProfilePic.layer.zPosition &gt;= viewHeader.layer.zPosition){
                viewHeader.layer.zPosition = 2;
            }
      }
    }

    // Apply Transformations
    viewHeader.layer.transform = headerTransform;
    imgVwProfilePic.layer.transform = avatarTransform;
}
</code></pre>

<p>现在,我不知道我必须为该 ImageView 设置 anchor 。但我不知道我会在哪里设置它。我在 <code>viewDidLoad</code> 中设置了它,但它改变了该 ImageView 的原始框架。</p>

<pre><code>- (void)viewDidLoad
{
    imgVwProfilePic.layer.anchorPoint = CGPointMake(1, 1); // 1,1 for bottom right corner...
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>你是对的,你必须设置 anchor 位置(IIRC 是一对在 范围内的标量,用于中心的相对 X 和相对 Y 位置)。</p>

<p>之后,图层的“位置”属性(以及扩展 View 的原点)将是 w.r.t。该 anchor 位置,因此您必须重新调整框架。您可以尝试覆盖</p>

<pre><code>- (void) setFrame:(CGRect)frame {
    CGPoint center = CGPointMake ( frame.origin.x+0.5*frame.size.width , frame.origin.y+0.5*frame.size.height ) ;
    viewHeader.layer.position = center ;
    CGRect bounds = CGRectMake ( 0,0 , frame.size.width,frame.size.height ) ;
    viewHeader.layer.bounds = bounds ;
}
</code></pre>

<p>并让它负责处理。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 不是从中心缩放 UIView,而是使用 CATransform3DScale 从右下角缩放,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/30869998/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/30869998/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 不是从中心缩放 UIView,而是使用 CATransform3DScale 从右下角缩放