Ограничения не обновляются при изменении границ происхождения UIView - PullRequest
0 голосов
/ 18 июня 2019

У меня есть UIView A, который содержит другой UIView B (подпредставление A).Существует еще один UIView C (подпредставитель родителя UIView A), и к нему применены ограничения, так что верхний якорь UIView C выровнен с нижним якорем UIView B, а левый якорь UIView C выровнен с левым якорем UIViewB.

Теперь, когда я пытаюсь изменить источник границ UIView A, расположение UIView B обновляется, но местоположение UIView C не изменяется, что приводит к нарушению исходных ограничений.

Я пытался сделать setNeedsLayout и updateConstraints, но ничего не работает.

Когда UIView C является дочерним для UIView A, тогда он работает нормально.

Как сделать так, чтобы UIView C был родным для UIView A, и поддерживать ограничения при изменении источника границ UIView A?

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Вы пытаетесь смешать и сопоставить явные настройки рамки / границ с ограничениями автоматического макета. Это, как вы видите, не сработает.

Когда вы запустите эту строку:

[[recognizer view] setBounds:CGRectMake(100, 100, bounds.size.width, bounds.size.height)];

Вы изменяете bounds представления. Это не меняет никаких ограничений. (На самом деле, установка bounds даже не меняет frame, но это другая проблема.)

Если вы хотите переместить представление и сохранить ограничения между этим представлением и другими элементами, вам необходимо обновить ограничения для этого представления, а не для его границ (или фрейма) .

Таким образом, вы хотите сохранить ссылки на ограничения или найти их при необходимости и обновить значения .constant по желанию.

Вот пример изменения центра вашего постукивающего вида путем нахождения ограничений CenterX и CenterY (вместо сохранения ссылок):

- (void)handleGesture:(UIGestureRecognizer*)recognizer
{

    // get the view that was tapped
    UIView *tappedView = [recognizer view];

    // get that view's constraints
    NSArray *constraints = [tappedView constraints];

    // we want to find the CenterX constraint
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeCenterX];
    NSArray *filteredArray = [constraints filteredArrayUsingPredicate:predicate];

    // if it doesn't have a CenterX constraint, return
    if(filteredArray.count == 0){
        return;
    }
    NSLayoutConstraint *centerX =  [filteredArray objectAtIndex:0];

    // we want to find the CenterY constraint
    predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeCenterY];
    filteredArray = [constraints filteredArrayUsingPredicate:predicate];

    // if it doesn't have a CenterY constraint, return
    if(filteredArray.count == 0){
        return;
    }
    NSLayoutConstraint *centerY =  [filteredArray objectAtIndex:0];

    // we now have references to the CenterX and CenterY constraints of the tapped view,
    // so we can change the .constant values and the related constraints to the other view will be maintained

    [UIView animateWithDuration:0.15
                     animations:^
     {
         centerX.constant -= 100.0;
         centerY.constant -= 100.0;
     }
                     completion:^(BOOL finished)
     {

     }];

}
0 голосов
/ 18 июня 2019

Прежде всего, у вас есть небольшая ошибка

левый якорь UIView C выровнен с левым якорем UIView B.

NSLayoutConstraint *left = [myView.leftAnchor constraintEqualToAnchor:secondView.rightAnchor constant:0];

Попробуйте позвонить

[self.view layoutIfNeeded];

после изменения границ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...