iOS:CGAffineTransformScale移动我的对象

前端之家收集整理的这篇文章主要介绍了iOS:CGAffineTransformScale移动我的对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
基于一个问题,我有 earlier.

尝试转换标签的简单按钮.我希望它减少0.5,这是有效的,但由于某种原因,它也移动对象,因为它.标签跳到左边,然后转换.

- (IBAction)btnTest:(id)sender
{

    [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        lblTest.transform = CGAffineTransformScale(lblTest.transform,0.5f,0.5f);
    }completion:^(BOOL finished) {
        if(finished){
            NSLog(@"DONE");
        }
    }];
}

解决方法

我认为您正在使用自动布局的问题:在自动布局中,如果您有一个领先的和/或顶级约束,则在使用CGAffineTransformMakeScale进行扩展后,将重新应用前导/顶部约束,并且您的控件将继续你为了确保约束仍然满足.

您可以关闭自动布局(这是简单的答案),也可以:

>等待直到viewDidAppear(因为IB中定义的约束被应用,并且控件将被放置在我们想要的位置,并且其中心属性将是可靠的);
>现在我们有控件的中心,使用NSLayoutAttributeCenterX和NSLayoutAttributeCenterY约束替换主要和最重要的约束,使用中心属性的值来设置NSLayoutConstraint的常量,如下所示.

从而:

// don't try to do this in `viewDidLoad`; do it in `viewDidAppear`,where the constraints
// have already been set

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self replaceLeadingAndTopWithCenterConstraints:self.imageView];
}

// Because our gesture recognizer scales the UIView,it's quite important to make
// sure that we don't have the customary top and leading constraints,but rather
// have constraints to the center of the view. Thus,this looks for leading constraint
// and if found,removes it,replacing it with a centerX constraint. Likewise if it
// finds a top constraint,it replaces it with a centerY constraint.
//
// Having done that,we can now do `CGAffineTransformMakeScale`,and it will keep the
// view centered when that happens,avoiding weird UX if we don't go through this
// process.

- (void)replaceLeadingAndTopWithCenterConstraints:(UIView *)subview
{
    CGPoint center = subview.center;

    NSLayoutConstraint *leadingConstraint = [self findConstraintOnItem:subview
                                                             attribute:NSLayoutAttributeLeading];
    if (leadingConstraint)
    {
        NSLog(@"Found leading constraint");

        [subview.superview removeConstraint:leadingConstraint];

        [subview.superview addConstraint:[NSLayoutConstraint constraintWithItem:subview
                                                                      attribute:NSLayoutAttributeCenterX
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:subview.superview
                                                                      attribute:NSLayoutAttributeTop
                                                                     multiplier:1.0
                                                                       constant:center.x]];
    }

    NSLayoutConstraint *topConstraint = [self findConstraintOnItem:subview
                                                         attribute:NSLayoutAttributeTop];

    if (topConstraint)
    {
        NSLog(@"Found top constraint");

        [subview.superview removeConstraint:topConstraint];

        [subview.superview addConstraint:[NSLayoutConstraint constraintWithItem:subview
                                                                      attribute:NSLayoutAttributeCenterY
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:subview.superview
                                                                      attribute:NSLayoutAttributeLeft
                                                                     multiplier:1.0
                                                                       constant:center.y]];
    }
}

- (NSLayoutConstraint *)findConstraintOnItem:(UIView *)item attribute:(NSLayoutAttribute)attribute
{
    // since we're looking for the item's constraints to the superview,let's
    // iterate through the superview's constraints

    for (NSLayoutConstraint *constraint in item.superview.constraints)
    {
        // I believe that the constraints to a superview generally have the
        // `firstItem` equal to the subview,so we'll try that first.

        if (constraint.firstItem == item && constraint.firstAttribute == attribute)
            return constraint;

        // While it always appears that the constraint to a superview uses the
        // subview as the `firstItem`,theoretically it's possible that the two
        // could be flipped around,so I'll check for that,too:

        if (constraint.secondItem == item && constraint.secondAttribute == attribute)
            return constraint;
    }

    return nil;
}

您的实现细节可能会有所不同,具体取决于您如何定义要缩放的控件的约束(在我的情况下,引导和顶部基于超级视图,这使得它更容易),但希望它可以说明解决方案,去除这些约束,并根据中心添加新约束.

如果您不想通过查找有问题的约束来迭代,就像上面所述,为顶层和前导约束定义一个IBOutlet,这大大简化了过程.这个示例代码是从一个项目中获取的,由于各种原因,我无法使用IBOutlet进行NSLayoutConstraint引用.但是使用IBOutlet引用的约束绝对是一个更简单的方法(如果你坚持使用自动布局).

例如,如果您进入Interface Builder,您可以突出显示所涉及的约束,并将控件拖到助手编辑器中,以使您的IBOutlet:

如果你这样做,而不是迭代所有的约束,你现在可以说,例如:

if (self.imageViewVerticalConstraint)
{
    [self.view removeConstraint:self.imageViewVerticalConstraint];

    // create the new constraint here,like shown above
}

坦白说,我希望Interface Builder有能力立即开始定义这些约束(即,而不是“superview”左边的控制领先“约束,”superview“左边的控制中心)约束),但是我不要以为可以在IB中完成,所以我以编程方式改变了我的约束.但是,通过这个过程,我现在可以扩展控制,而不是因为约束而在我身上移动.

如0x7fffffff所示,如果将CATransform3DMakeScale应用于图层,则它不会自动应用约束,因此您将不会看到它像将CGAffineTransformMakeScale应用于视图一样移动.但是,如果您做任何事情来重新应用约束(setNeedsLayout或对任何UIView对象进行任何更改可能会导致重新应用约束),视图将在您的身上移动.因此,如果在重新应用约束之前将层的变换恢复为身份标识,则可能会“潜入”,但关闭自动布局或修复约束可能最为安全.

原文链接:https://www.f2er.com/iOS/337481.html

猜你在找的iOS相关文章