UIView에 영향을 미치는 모든 제약 조건 제거


87

몇 가지 제약 조건을 통해 화면에 배치되는 UIView가 있습니다. 제약 중 일부는 수퍼 뷰가 소유하고 다른 제약은 다른 조상이 소유합니다 (예 : UIViewController의 뷰 속성).

이 모든 오래된 제약을 제거하고 새로운 제약을 사용하여 새로운 곳에 배치하고 싶습니다.

모든 단일 제약 조건에 대해 IBOutlet을 생성하지 않고 어떤 뷰가 해당 제약 조건을 소유하는지 기억하지 않고 어떻게이 작업을 수행 할 수 있습니까?

정교하게 설명하기 위해 순진한 접근 방식은 각 제약 조건에 대해 IBOutlet을 생성 한 다음 다음과 같은 코드를 호출하는 것입니다.

[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];

이 코드의 문제점은 가장 단순한 경우에도 2 개의 IBOutlet을 생성해야한다는 것입니다. 복잡한 레이아웃의 경우 필요한 IBOutlet 4 개 또는 8 개에 쉽게 도달 할 수 있습니다. 또한 제약 조건을 제거하라는 호출이 적절한 뷰에서 호출되는지 확인해야합니다. 예를 들어, 그는 상상 myViewsLeftConstraint에 의해 소유된다 viewA. 실수로을 호출 [self.view removeConstraint:self.myViewsLeftConstraint]하면 아무 일도 일어나지 않습니다.

참고 : constraintsAffectingLayoutForAxis 메소드 는 유망 해 보이지만 디버깅 목적으로 만 사용됩니다.


업데이트 : 내가 받고있는 대부분의 답변 self.constraintsself.superview.constraints, 또는 일부 변형을 처리합니다. 이러한 방법은 뷰에 영향을주는 제약 조건이 아닌 뷰가 소유 한 제약 조건 만 반환하므로 이러한 솔루션은 작동 하지 않습니다 .

이러한 솔루션의 문제를 명확히하려면 다음 뷰 계층 구조를 고려하십시오.

  • 할아버지
    • 아버지
      • 나를
        • 아들
      • 동료
    • 삼촌

이제 다음 제약 조건을 만들고 항상 가장 가까운 공통 조상에 연결한다고 상상해보십시오.

  • C0 : 나 : 아들과 같은 탑 (나 소유)
  • C1 : 나 : 너비 = 100 (내가 소유)
  • C2 : 나 : 형제와 같은 키 (아버지 소유)
  • C3 : 나 : 삼촌과 같은상의 (할아버지 소유)
  • C4 : 나 : 할아버지와 같은 왼쪽 (Grandfather 소유)
  • C5 : 형제 : 아버지와 같은 왼쪽 (아버지 소유)
  • C6 : 삼촌 : 할아버지와 같은 왼쪽 (할아버지 소유)
  • C7 : 아들 : 딸과 같은 왼쪽 (나 소유)

이제에 영향을 미치는 모든 제약을 제거하고 싶다고 상상해보십시오 Me. 적절한 솔루션은 제거해야 [C0,C1,C2,C3,C4]하며 다른 것은 없어야 합니다.

내가 self.constraints(self가 Me 인 경우)를 사용 하면를 얻을 것입니다 [C0,C1,C7]. 왜냐하면 그것들은 Me가 소유 한 유일한 제약이기 때문입니다. 이것이 누락 되었기 때문에 분명히 이것을 제거하는 것으로 충분하지 않을 것 [C2,C3,C4]입니다. 또한 C7불필요하게 제거 하고 있습니다.

self.superview.constraints(self is Me)를 사용하면 [C2,C5]아버지가 소유 한 제약이기 때문에 를 얻습니다 . 이후 분명히 우리는 이것들을 제거 할 수 C5는 전혀 관련이있다 Me.

내가 사용 grandfather.constraints하면 얻을 것이다 [C3,C4,C6]. 다시 말하지만,이 모든 것을 제거 할 수는 없습니다 C6.

브 루트 포스 접근법 (자체 포함) 뷰의 각 선조의 위에 루프이고, 만약 볼 firstItem또는 secondItem뷰 자체이다; 그렇다면 해당 제약 조건을 제거하십시오. 이것은 올바른 솔루션으로 이어지고 [C0,C1,C2,C3,C4], 그리고 그 제약들만 반환 합니다.

그러나 전체 조상 목록을 반복하는 것보다 더 우아한 해결책이 있기를 바랍니다.


제거하려는 모든 제약 조건에 식별자를 추가하는 것은 어떻습니까? 이렇게하면 그들을위한 콘센트를 유지할 필요가 없습니다.
nsuinteger

답변:


69

이 접근 방식은 저에게 효과적이었습니다.

@interface UIView (RemoveConstraints)

- (void)removeAllConstraints;

@end


@implementation UIView (RemoveConstraints)

- (void)removeAllConstraints
{
    UIView *superview = self.superview;
    while (superview != nil) {
        for (NSLayoutConstraint *c in superview.constraints) {
            if (c.firstItem == self || c.secondItem == self) {
                [superview removeConstraint:c];
            }
        }
        superview = superview.superview;
    }

    [self removeConstraints:self.constraints];
    self.translatesAutoresizingMaskIntoConstraints = YES;
}

@end

실행이 완료되면 자동 크기 조정 제약 조건을 생성하기 때문에 뷰가 그대로 유지됩니다. 이 작업을 수행하지 않으면 일반적으로보기가 사라집니다. 또한 상위 뷰에서 제약 조건을 제거하는 것이 아니라 상위 뷰에 영향을 미치는 제약 조건이있을 수 있으므로 계속 위로 이동합니다.


Swift 4 버전

extension UIView {
    
    public func removeAllConstraints() {
        var _superview = self.superview
        
        while let superview = _superview {
            for constraint in superview.constraints {
                
                if let first = constraint.firstItem as? UIView, first == self {
                    superview.removeConstraint(constraint)
                }
                
                if let second = constraint.secondItem as? UIView, second == self {
                    superview.removeConstraint(constraint)
                }
            }
            
            _superview = superview.superview
        }
        
        self.removeConstraints(self.constraints)
        self.translatesAutoresizingMaskIntoConstraints = true
    }
}

3
이것은 공식적인 대답이어야합니다.
Jason Crocker 2015

왜 self.translatesAutoresizingMaskIntoConstraints = YES가 있습니까? ? 제약 조건으로 설정하는 뷰에 문자 그대로 이것을 원하지 않습니까?
lensovet 2015-08-14

4
제약 조건을 제거하고 있으므로 다른 제약 조건을 제자리에
고정한

디버깅 목적으로 뷰에 대한 모든 제약 조건 을 기록 해야했고 이를 위해이 답변을 약간 수정할 수있었습니다. +1
chiliNUT

이로 인해 C7. 그러나, 당신이 제거하면 해결하기 쉬워야한다 [self removeConstraints:self.constraints];변화 UIView *superview = self.superview;UIView *superview = self;.
Senseful

49

지금까지 찾은 유일한 해결책은 수퍼 뷰에서 뷰를 제거하는 것입니다.

[view removeFromSuperview]

이것은 레이아웃에 영향을 미치는 모든 제약을 제거하고 수퍼 뷰에 추가 할 준비가되어 있고 새로운 제약이 첨부 된 것처럼 보입니다. 그러나 계층 구조에서 모든 하위보기를 잘못 제거하고 잘못 제거합니다 [C7].


제약 조건의 firstItem 및 secondItem 속성을 사용하여 뷰에 적용되는지 확인하고 뷰 계층 구조를 반복하여 모두 찾을 수 있습니다. 그래도 제거하고 다시 추가하는 것이 더 나은 해결책이라고 생각합니다. 이것은 매우 나쁜 일인 것처럼 보이기 때문에 귀하의 사용 사례를보고 싶습니다. 다른 뷰가 적절하게 레이아웃하기 위해 이러한 제약 조건에 의존 할 수 있으므로 제약 조건이 완전히 무효화 될 수 있습니다.
bjtitus 2014-06-25

@bjtitus : 좋은 지적입니다. 그러나이 특정 경우에는 종속 항목이없는 뷰의 위치를 ​​변경합니다. 배치 할 위치를 알기 위해 다른 뷰를 사용하고 배치 할 위치를 알기 위해이를 사용하는 뷰가 없습니다.
Senseful 2014-06-25

유일한 해결책은 아니지만 매우 간단합니다. 내 사용 사례에서 방금 superview에서 뷰를 제거한 다음 나중에 다시 추가했습니다.
Marián Černý

48

다음을 수행하여 뷰의 모든 제약 조건을 제거 할 수 있습니다.

self.removeConstraints(self.constraints)

편집 : 모든 하위보기의 제약 조건을 제거하려면 Swift에서 다음 확장을 사용하십시오.

extension UIView {
    func clearConstraints() {
        for subview in self.subviews {
            subview.clearConstraints()
        }
        self.removeConstraints(self.constraints)
    }
}

22
이 솔루션의 문제점은이 뷰가 소유하는 제약 (예 : 너비 및 높이) 만 제거한다는 것입니다. 선행 및 상단 제약과 같은 것은 제거하지 않습니다.
Senseful

2
위의 의견을 확인하지 않았습니다. 그러나 위와 동일하거나 더 잘 작동 할 것이라고 생각합니다. [NSLayoutConstraint deactivateConstraints : self.constraints];
emdog4 2014 년

2
그것은 원래 솔루션과 동일한 문제로 고통받을 것입니다. self.constraintsself영향을주는 모든 제약이 아닌 소유 한 제약 만 반환합니다 self.
Senseful

1
나는 당신이 지금 말하는 것을 이해합니다. 내 대답 에서 UITableViewCell의 contentView에서 제약 조건을 제거하고 있습니다. 그런 다음 updateConstraints 메소드는 모든 하위보기에 대한 제약 조건을 추가하고 레이아웃을 재설정합니다. 위의 첫 번째 주석에서 self.view.constraints를 입력해야합니다. self.view와 self.contentView는 모두 뷰 계층 구조의 맨 위에 있습니다. self.view 또는 self.contentView에서 translatesAutoresizingMasksToConstraints = YES를 설정하는 것은 나쁜 생각입니다. ;-). addSubview에 대한 호출이 마음에 들지 않습니다. 내 updateConstraints 메서드에서 계층 구조에서 뷰를 제거하면 불필요한 imo가 보입니다.
emdog4 2014 년

나는 왜 이와 같은 솔루션이 내가하려는 일에 대해 작동하지 않는지 보여주기 위해 질문을 업데이트했습니다. UITableViewCell 내에 있다고 가정하면 contentView에 해당하는 것은 Grandfather입니다. 따라서 솔루션이 잘못 제거 [C6]되고 잘못 제거되지 않습니다 [C0,C1,C2].
Senseful

20

Apple Developer Documentation 에 따라이를 달성하는 방법에는 두 가지 방법이 있습니다.

1. NSLayoutConstraint.deactivateConstraints

이것은 한 번의 호출로 일련의 제약 조건을 비활성화하는 쉬운 방법을 제공하는 편리한 방법입니다. 이 메서드의 효과는 각 제약 조건의 isActive 속성을 false로 설정하는 것과 같습니다. 일반적으로이 방법을 사용하는 것이 각 제약 조건을 개별적으로 비활성화하는 것보다 효율적입니다.

// Declaration
class func deactivate(_ constraints: [NSLayoutConstraint])

// Usage
NSLayoutConstraint.deactivate(yourView.constraints)

2. UIView.removeConstraints(> = iOS 8.0에서 더 이상 사용되지 않음)

iOS 8.0 이상용으로 개발하는 경우 removeConstraints : 메서드를 직접 호출하는 대신 NSLayoutConstraint 클래스의 deactivateConstraints : 메서드를 사용합니다. deactivateConstraints : 메서드는 올바른 뷰에서 제약 조건을 자동으로 제거합니다.

// Declaration
func removeConstraints(_ constraints: [NSLayoutConstraint])`

// Usage
yourView.removeConstraints(yourView.constraints)

Storyboards 또는 XIBs를 사용 하는 것은 시나리오에서 언급 한대로 제약 조건을 구성하는 데 매우 고통 스러울 수 있으므로 제거하려는 각 항목에 대해 IBOutlet을 만들어야합니다. 그럼에도 불구하고 대부분의 Interface Builder경우 해결하는 것보다 더 많은 문제가 발생합니다.

따라서 매우 동적 인 콘텐츠와 뷰의 다른 상태를 가질 때 다음을 제안합니다.

  1. 프로그래밍 방식으로보기 만들기
  2. 레이아웃 및 NSLayoutAnchor 사용
  3. 나중에 제거 될 수있는 각 제약 조건을 배열에 추가합니다.
  4. 새 상태를 적용하기 전에 매번 지우십시오.

간단한 코드

private var customConstraints = [NSLayoutConstraint]()

private func activate(constraints: [NSLayoutConstraint]) {
    customConstraints.append(contentsOf: constraints)
    customConstraints.forEach { $0.isActive = true }
}

private func clearConstraints() {
    customConstraints.forEach { $0.isActive = false }
    customConstraints.removeAll()
}

private func updateViewState() {
    clearConstraints()

    let constraints = [
        view.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
        view.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
        view.topAnchor.constraint(equalTo: parentView.topAnchor),
        view.bottomAnchor.constraint(equalTo: parentView.bottomAnchor)
    ]

    activate(constraints: constraints)

    view.layoutIfNeeded()
}

참고 문헌

  1. NSLayoutConstraint
  2. UIView

2
조심해. 내장 콘텐츠 크기를 지정하는 뷰에는 iOS에서 NSContentSizeLayoutConstraint가 자동으로 추가됩니다. 일반 yourView.constraints 속성에 액세스하여이를 제거하면 해당 뷰에서 자동 레이아웃이 중단됩니다.
TigerCoding 2017

이 솔루션의 문제점은이 뷰가 소유하는 제약 (예 : 너비 및 높이) 만 제거한다는 것입니다. 선행 및 상단 제약과 같은 것은 제거하지 않습니다.
Senseful

예, Senseful이 말한 것. 이러한 방법이 존재하지만 질문이 실제로 묻는 문제를 스스로 해결하지는 못합니다.
GSnyder 2018

18

Swift에서 :

import UIKit

extension UIView {

    /**
     Removes all constrains for this view
     */
    func removeConstraints() {

        let constraints = self.superview?.constraints.filter{
            $0.firstItem as? UIView == self || $0.secondItem as? UIView == self
        } ?? []

        self.superview?.removeConstraints(constraints)
        self.removeConstraints(self.constraints)
    }
}

보기에 'superview!'에 superview가 없으면 충돌이 발생합니다. :) '하자의 수퍼은 수퍼 = 경우'는에 일부를 넣어
Bersaelor

1
모든 제약이 제거되지는 않습니다. 제약 조건은 영향을받는 두 뷰의 가장 가까운 부모를 취
하므로이

2
아마도 더 정확한 것은 if c.firstItem === self캐스팅 대신 신원을 비교 as? UIView하고 동등성을 확인하는 것입니다==
user1244109

removeConstraints : from apple doc를 사용해서는 안됩니다. // removeConstraints 메소드는 향후 릴리스에서 더 이상 사용되지 않으므로 피해야합니다. 대신 + [NSLayoutConstraint deactivateConstraints :]를 사용합니다.
이오 니스트

@eonist 대답은 3 년 전입니다. 비판 대신 편집해야합니다.
알렉산더 볼코프

5

세부

  • Xcode 10.2.1 (10E1001), Swift 5

해결책

import UIKit

extension UIView {

    func removeConstraints() { removeConstraints(constraints) }
    func deactivateAllConstraints() { NSLayoutConstraint.deactivate(getAllConstraints()) }
    func getAllSubviews() -> [UIView] { return UIView.getAllSubviews(view: self) }

    func getAllConstraints() -> [NSLayoutConstraint] {
        var subviewsConstraints = getAllSubviews().flatMap { $0.constraints }
        if let superview = self.superview {
            subviewsConstraints += superview.constraints.compactMap { (constraint) -> NSLayoutConstraint? in
                if let view = constraint.firstItem as? UIView, view == self { return constraint }
                return nil
            }
        }
        return subviewsConstraints + constraints
    }

    class func getAllSubviews(view: UIView) -> [UIView] {
        return view.subviews.flatMap { [$0] + getAllSubviews(view: $0) }
    }
}

용법

print("constraints: \(view.getAllConstraints().count), subviews: \(view.getAllSubviews().count)")
view.deactivateAllConstraints()

1
꽤 좋다.
eonist

2

신속한 솔루션 :

extension UIView {
  func removeAllConstraints() {
    var view: UIView? = self
    while let currentView = view {
      currentView.removeConstraints(currentView.constraints.filter {
        return $0.firstItem as? UIView == self || $0.secondItem as? UIView == self
      })
      view = view?.superview
    }
  }
}

두 요소 사이의 제약은 공통 조상이 유지하므로 모든 부모를 살펴 보는 것이 중요하므로이 답변에 자세히 설명 된 수퍼 뷰를 지우는 것만으로 는 충분하지 않으며 나중에 심각한 놀라움을 겪을 수 있습니다.


2

이전 답변을 기반으로 함 (swift 4)

전체 계층 구조를 크롤링하지 않으려는 경우 ImmediateConstraints를 사용할 수 있습니다.

extension UIView {
/**
 * Deactivates immediate constraints that target this view (self + superview)
 */
func deactivateImmediateConstraints(){
    NSLayoutConstraint.deactivate(self.immediateConstraints)
}
/**
 * Deactivates all constrains that target this view
 */
func deactiveAllConstraints(){
    NSLayoutConstraint.deactivate(self.allConstraints)
}
/**
 * Gets self.constraints + superview?.constraints for this particular view
 */
var immediateConstraints:[NSLayoutConstraint]{
    let constraints = self.superview?.constraints.filter{
        $0.firstItem as? UIView === self || $0.secondItem as? UIView === self
        } ?? []
    return self.constraints + constraints
}
/**
 * Crawls up superview hierarchy and gets all constraints that affect this view
 */
var allConstraints:[NSLayoutConstraint] {
    var view: UIView? = self
    var constraints:[NSLayoutConstraint] = []
    while let currentView = view {
        constraints += currentView.constraints.filter {
            return $0.firstItem as? UIView === self || $0.secondItem as? UIView === self
        }
        view = view?.superview
    }
    return constraints
}
}

2

다음 방법을 사용하여보기에서 모든 제약 조건을 제거합니다.

.h 파일 :

+ (void)RemoveContraintsFromView:(UIView*)view 
    removeParentConstraints:(bool)parent 
    removeChildConstraints:(bool)child;

.m 파일 :

+ (void)RemoveContraintsFromView:(UIView *)view 
    removeParentConstraints:(bool)parent 
    removeChildConstraints:(bool)child
{
    if (parent) {
        // Remove constraints between view and its parent.
        UIView *superview = view.superview;
        [view removeFromSuperview];
        [superview addSubview:view];
    }

    if (child) {
        // Remove constraints between view and its children.
        [view removeConstraints:[view constraints]];
    }
}

당신은 또한 수 있습니다 이 게시물 읽기 더 잘 후드 뒤에 작동 방법을 이해하는 것이 내 블로그에 있습니다.

좀 더 세부적으로 제어해야하는 경우, 나는 거라고 강하게 로 전환 조언 벽돌 , 제대로 프로그래밍 제약을 처리하기 위해 필요할 때마다 사용할 수있는 강력한 프레임 워크 클래스입니다.


2
형제 자매는 요?
zrslv

2

더 쉽고 효율적인 방법은 superView에서보기를 제거하고 다시 하위보기로 추가하는 것입니다. 이로 인해 모든 서브 뷰 제약이 자동으로 제거됩니다 .😉


1

ObjectiveC로

[self.superview.constraints enumerateObjectsUsingBlock:^(__kindof NSLayoutConstraint * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLayoutConstraint *constraint = (NSLayoutConstraint *)obj;
        if (constraint.firstItem == self || constraint.secondItem == self) {
            [self.superview removeConstraint:constraint];
        }
    }];
    [self removeConstraints:self.constraints];
}

0

다음과 같이 사용할 수 있습니다.

[viewA.superview.constraints enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLayoutConstraint *constraint = (NSLayoutConstraint *)obj;
    if (constraint.firstItem == viewA || constraint.secondItem == viewA) {
        [viewA.superview removeConstraint:constraint];
    }
}];

[viewA removeConstraints:viewA.constraints];

기본적으로 이것은 viewA의 superview에 대한 모든 제약을 열거하고 viewA와 관련된 모든 제약을 제거합니다.

그런 다음 두 번째 부분은 viewA의 제약 조건 배열을 사용하여 viewA에서 제약 조건을 제거합니다.


1
이 솔루션의 문제점은 수퍼 뷰가 소유 한 제약 조건 만 제거한다는 것입니다. 뷰에 영향을 미치는 모든 제약 조건을 제거하지는 않습니다. (예를
들어이

이 솔루션이 작동하지 않는 이유를 보여주기 위해 질문을 업데이트했습니다. 이것은 내가 위에서 언급 한 무차별 대입 솔루션에 가장 가깝기 때문에 정확에 가장 가깝습니다. 그러나이 솔루션은를 잘못 제거 [C7]하고 잘못 제거 하지 않습니다 [C3,C4].
Senseful

계층을 크롤링하는 방법을 설계 할 수 있습니다. 그러나 어쨌든 즉각적인 수퍼 뷰 위에 제약 조건을 추가해야하므로이 솔루션은 충분합니다. IMO
eonist

0

(2017 년 7 월 31 일 현재)

SWIFT 3

self.yourCustomView.removeFromSuperview()
self.yourCustomViewParentView.addSubview(self.yourCustomView)

목표 C

[self.yourCustomView removeFromSuperview];
[self.yourCustomViewParentView addSubview:self.yourCustomView];

이것은 UIView에 존재하는 모든 제약을 빠르게 제거하는 가장 쉬운 방법입니다. 새로운 제약 조건 또는 나중에 새로운 프레임으로 UIView를 다시 추가하십시오 =)


0

재사용 가능한 시퀀스 사용

나는 이것을 더 '재사용 가능한'방식으로 접근하기로 결정했습니다. 뷰에 영향을 미치는 모든 제약 조건을 찾는 것이 위의 모든 항목의 기초이므로 소유 뷰와 함께 모든 제약 조건을 반환하는 사용자 지정 시퀀스를 구현하기로 결정했습니다.

할 첫 번째 일은에 확장을 정의하는 것입니다 ArraysNSLayoutConstraint그 반환 특정 뷰에 영향을 미치는 모든 요소.

public extension Array where Element == NSLayoutConstraint {

    func affectingView(_ targetView:UIView) -> [NSLayoutConstraint] {

        return self.filter{

            if let firstView = $0.firstItem as? UIView,
                firstView == targetView {
                return true
            }

            if let secondView = $0.secondItem as? UIView,
                secondView == targetView {
                return true
            }

            return false
        }
    }
}

그런 다음 해당 뷰에 영향을주는 모든 제약 조건을 실제로 소유하는 뷰와 함께 반환하는 사용자 지정 시퀀스에서 해당 확장을 사용합니다 (뷰 계층의 어느 위치 에나있을 수 있음).

public struct AllConstraintsSequence : Sequence {

    public init(view:UIView){
        self.view = view
    }

    public let view:UIView

    public func makeIterator() -> Iterator {
        return Iterator(view:view)
    }

    public struct Iterator : IteratorProtocol {

        public typealias Element = (constraint:NSLayoutConstraint, owningView:UIView)

        init(view:UIView){
            targetView  = view
            currentView = view
            currentViewConstraintsAffectingTargetView = currentView.constraints.affectingView(targetView)
        }

        private let targetView  : UIView
        private var currentView : UIView
        private var currentViewConstraintsAffectingTargetView:[NSLayoutConstraint] = []
        private var nextConstraintIndex = 0

        mutating public func next() -> Element? {

            while(true){

                if nextConstraintIndex < currentViewConstraintsAffectingTargetView.count {
                    defer{nextConstraintIndex += 1}
                    return (currentViewConstraintsAffectingTargetView[nextConstraintIndex], currentView)
                }

                nextConstraintIndex = 0

                guard let superview = currentView.superview else { return nil }

                self.currentView = superview
                self.currentViewConstraintsAffectingTargetView = currentView.constraints.affectingView(targetView)
            }
        }
    }
}

마지막으로 UIView간단한 for-each 구문으로 액세스 할 수있는 간단한 속성에서 모든 제약 조건을 노출 하도록 확장을 선언 합니다.

extension UIView {

    var constraintsAffectingView:AllConstraintsSequence {
        return AllConstraintsSequence(view:self)
    }
}

이제 뷰에 영향을 미치는 모든 제약을 반복하고 원하는 작업을 수행 할 수 있습니다.

식별자 나열 ...

for (constraint, _) in someView.constraintsAffectingView{
    print(constraint.identifier ?? "No identifier")
}

비활성화 ...

for (constraint, _) in someView.constraintsAffectingView{
    constraint.isActive = false
}

또는 완전히 제거하십시오 ...

for (constraint, owningView) in someView.constraintsAffectingView{
    owningView.removeConstraints([constraint])
}

즐겨!


0

빠른

다음 UIView Extension은 뷰의 모든 Edge 제약 조건을 제거합니다.

extension UIView {
    func removeAllConstraints() {
        if let _superview = self.superview {
            self.removeFromSuperview()
            _superview.addSubview(self)
        }
    }
}

-1

특정보기에서 모든 제약 조건을 비활성화하는 방법입니다.

 NSLayoutConstraint.deactivate(myView.constraints)

이 솔루션의 문제점은이 뷰가 소유하는 제약 (예 : 너비 및 높이) 만 제거한다는 것입니다. 선행 및 상단 제약과 같은 것은 제거하지 않습니다.
Senseful
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.