런타임에 특정 하위보기에 대한 자동 레이아웃을 비활성화 할 수 있습니까?


104

프로그래밍 방식으로 프레임을 조작해야하는 뷰가 있습니다. 프레임 원점을 조작하여 수퍼 뷰를 스크롤하고 확대 / 축소하는 콘텐츠로 래핑되는 일종의 문서 뷰입니다. Autolayout은 런타임에 이것과 싸 웁니다.

자동 레이아웃을 완전히 비활성화하는 것은 다른 뷰의 레이아웃을 처리하는 데 합리적으로 사용될 수 있기 때문에 약간 가혹 해 보입니다. 내가 원하는 것은 일종의 "null 제약"인 것 같습니다.

답변:


168

나는 같은 문제가 있었다. 그러나 나는 그것을 해결했다.
예, UIViewXcode 4.3 이상에서 기본적으로 설정되는 전체 xib 또는 스토리 보드에 대해 비활성화하는 대신 특정에 대해 런타임에 자동 레이아웃을 비활성화 할 수 있습니다 .

설정 translatesAutoresizingMaskIntoConstraintsYES당신이 당신의 서브 뷰의 프레임을 설정하기 전에 :

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
이것은 많은 뷰를 가진 좀 더 복잡한 경우에 과잉처럼 보입니다. 이처럼 간단한 것은 괜찮습니다.
esh

@MuhammadAamirALi 하위 뷰를 제거한 다음 다시 추가하면 성능이 저하 될 수 있습니다. 더 나은 솔루션을 보관할 수 있습니까?
Nhat Dinh

2
@DinhNhat 나는 대답을 명확히했습니다. 하위보기를 제거하고 다시 추가 할 필요가 없습니다.
Leandros 2014

5
"동시에 제약 조건을 충족 할 수 없습니다."라는 경고가 표시됩니다.
NSPratik

1
이 같은 특성을 발명 내 하루 ... translatesAutoresizingMaskIntoConstraints ... 저장 shakinghead
Tintenklecks

50

Autolayout이 런타임에 내 프레임 설정 중 일부를 재정의하는 비슷한 문제가있었습니다 (어떤 경우에는 새 뷰 컨트롤러를 푸시하는 동적 뷰가있었습니다 ... 푸시 한 다음 뒤로를 누르면 초기 뷰가 재설정 됨).

viewDidLayoutSubviewsView Controller 에 조작 코드를 넣어이 문제를 해결했습니다. 이것은 제약 조건 mojo가 호출 된 후에 호출되는 것처럼 보이지만 viewDidAppear 전에 호출되므로 사용자는 현명하지 않습니다.


1
self.navigationItem.titleView에서는 작동하지 않습니다. 여전히 프레임 변경을 존중하지 않습니다.
Henrik Erlandsson

1
제목보기의 프레임을 처리하려는 경우 컨테이너보기 안에 넣고 컨테이너보기를 navigationItem의 사용자 지정보기로 추가합니다.
jmstone617

2
이것은 나에게도 효과적이었습니다. 나는이 해결 방법을 발견하기 전에 속담의 벽에 머리를 두드리는 데 2 ​​시간 22 분을 낭비했다.
TMc 2014 년

고마워요 나는이 문제로 고생하는 두 번째 날에 있으며 이제 작동합니다!
apostolov

28

아마도로 설정 translatesAutoresizingMaskIntoConstraints하고 YES해당 뷰에 영향을 미치는 추가 제약 조건을 추가하지 않는 것만으로도 자동 레이아웃 시스템과 싸우지 않고 프레임을 설정할 수 있습니다.


17

iOS 8에서는 NSLayoutConstraint를 활성화하거나 비활성화 할 수 있습니다. 따라서 인터페이스 빌더를 사용하는 경우 모든 제약 조건을 OutletCollection에 추가 한 다음 다음을 사용하여 활성화 또는 비활성화합니다.

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

여기에서 사용하는 특정 응용 프로그램은 세로 및 가로 모드에서 다른 제약 조건을 가지고 있으며 장치의 회전에 따라 활성화 / 비활성화됩니다. 즉, 두 방향 모두에 대해 인터페이스 빌더에서 복잡한 레이아웃 변경을 모두 만들 수 있으며 자세한 자동 레이아웃 코드 없이도 자동 레이아웃을 사용할 수 있습니다.

또는 removeConstraints 및 addConstraints를 사용하여 활성화 / 비활성화 할 수 있습니다.


그런 오래된 질문을 가로 채서 죄송 합니다만, 처음에 다른 레이아웃에 대한 레이아웃 제약을 어떻게 추가했는지 물어봐도 될까요? 제약 조건을 활성화 / 비활성화하는 인터페이스 빌더 내에서 옵션을 찾을 수없는 것 같습니다. 아니면 단순히 두 레이아웃에 대한 제약 조건을 추가하고 유효하지 않은 (무시하는) 제약 조건에 대해 불평하는 인터페이스 빌더를 무시 했습니까?
말테

크기 클래스를 사용하여 할 수 있습니다 : developer.apple.com/library/ios/recipes/… ,하지만 iOS 7도 지원하고 크기 클래스가 iOS 7을 완전히 지원하지 않기 때문에 이런 식으로 할 수 없었습니다. 나는 상충되는 제약의 우선 ​​순위를 낮춤으로써 그것을했다. 이상적이지는 않지만 경고를 방지합니다. 나는 .... 어쨌든 그것을 어떻게 이런 생각
bandejapaisa

9

이것이 다른 사람에게 도움이 될지는 모르겠지만,이 일을 많이하게 되었기 때문에 이것을 편리하게하기 위해 카테고리를 썼습니다.

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

다음과 같이 사용합니다.

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

도움이되기를 바랍니다.


훌륭한 ! 수정 된 버전의 코드를 사용하여 모든 UIView에 대한 간단한 "hideControl"함수를 작성했습니다. 기본적으로 UIView의 높이를 0으로 설정하지만, 결정적으로 AutoLayout이 올바르게 처리하도록 코드를 사용합니다 ( "someView.hidden = TRUE"를 사용하는 것과 달리). 따라서 숨겨진 컨트롤 아래에 나타나고 수직 간격이 연결된 컨트롤은 이제 이전에 숨겨진 뷰가 나타난 간격을 채우기 위해 화면에서 위로 이동합니다.
Mike Gledhill 2014

6

xib / storyboard에서 원하는 UIView의 User Defined Runtime Attributes에서 translatesAutoresizingMaskIntoConstraints유형 Boolean, Value Yes를 설정할 수 있습니다 .


2
  • 4.5에서 프로젝트 열기
  • 스토리 보드 선택
  • 파일 검사기 열기
  • Interface Builder Document에서 'Use Autolayout'을 선택 취소하십시오.

일부보기에 자동 레이아웃을 사용하려는 경우 여러 스토리 보드로 분할 할 수 있습니다.


10
그러면 전체 스토리 보드 / 펜촉에 대한 자동 레이아웃이 비활성화됩니다. 내가 찾던 것은 스토리 보드 / 니브 내의 특정 하위 뷰가 자동 레이아웃을 사용하지 않고 나머지는 스토리 보드 / 펜촉이 지정한대로 수행하도록하는 방법 (이상적으로는 프로그래밍 방식)이었습니다.
terriblememory

여러 스토리 보드를 사용할 수 있으며 필요에 따라 자동 레이아웃이 있거나없는 스토리 보드를 호출 할 수 있습니다. // 디스플레이를위한 스토 보드 및 상세보기 컨트롤러 초기화 UIStoryboard * sb = [UIStoryboard storyboardWithName : @ "Storyboard"bundle : [NSBundle mainBundle]]; DetailViewController * dvController = [sb instantiateViewControllerWithIdentifier : entry.viewName];
Mike Bobbitt 2012-08-02

1

저에게는 프로그래밍 방식으로 하위 뷰를 생성하는 작업을 수행했습니다. 제 경우에는 자동 레이아웃이 중앙을 중심으로 회전해야하는 뷰를 엉망으로 만들었지 만이 뷰를 프로그래밍 방식으로 생성 한 후에는 작동했습니다.


1

내 견해로는 레이블과 텍스트가 있습니다. 라벨에는 팬 제스처가 있습니다. 드래그하는 동안 레이블이 잘 움직입니다. 그러나 텍스트 상자 키보드를 사용하면 레이블이 자동 레이아웃에 정의 된 원래 위치로 위치를 재설정합니다. 레이블에 대해 다음을 신속하게 추가하면 문제가 해결되었습니다. viewWillAppear에 추가했지만 대상 필드에 액세스 할 수있는 거의 모든 곳에서 추가 할 수 있습니다.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

이것은 스토리 보드 나 xib 파일이없는 프로젝트에서 나에게 일어났습니다. 모두 100 % 코드입니다. 하단에 광고 배너가 있었고 뷰 경계가 광고 배너에서 멈추기를 원했습니다. 뷰는로드 후 자동으로 크기가 조정됩니다. 이 페이지의 모든 해결책을 시도했지만 어느 것도 작동하지 않았습니다.

높이가 짧아 진 하위 뷰를 만들어 컨트롤러의 메인 뷰에 배치했습니다. 그런 다음 모든 콘텐츠가 하위 뷰에 들어갔습니다. 그것은 곡물에 반하는 것처럼 느껴지는 일을하지 않고도 문제를 매우 쉽게 해결했습니다.

창을 채우는 정상적인 크기가 아닌보기를 원한다면 하위보기를 사용해야한다고 생각합니다.


0

자동 레이아웃으로 시작된 프로젝트에 참여한 비슷한 시나리오가 발생했지만 여러보기를 동적으로 조정해야했습니다. 나를 위해 일한 것은 다음과 같습니다.

  1. 인터페이스 빌더에 배치 된 뷰 또는 구성 요소가 없습니다.

  2. alloc / init로 시작하여 프레임을 적절하게 설정하는 순전히 프로그래밍 방식으로 뷰를 추가하십시오.

  3. 끝난.


0

자동 레이아웃을 비활성화하는 대신 교체하려는 프레임으로 새 제약 조건을 계산합니다. 그것은 나에게 적절한 방법으로 보입니다. 제약 조건에 의존하는 구성 요소를 조정하는 경우 적절하게 조정하십시오.

예를 들어 두 뷰 (myView 및 otherView) 사이에 0의 수직 제약 조건이 있고 이동 제스처 또는 myView의 높이를 조정하는 무언가가있는 경우 조정 된 값으로 제약 조건을 다시 계산할 수 있습니다.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

자동 레이아웃을 사용하는 분들은 여기 에서 내 솔루션을 확인 하십시오 . 당신이 만드는해야 @IBOutlet조정할 다음 자신의 상수를 변경하려는 제약 S '이 (가) 있습니다.


-16

xib 파일 인 경우 :

  1. .xib 파일 선택
  2. "파일 소유자"를 선택하십시오.
  3. 유틸리티보기
  4. 클릭 : "파일 검사기"
  5. "인터페이스 빌더 문서"에서 "자동 레이아웃 사용"을 비활성화합니다.

1
아니요, 전체 xib에 대한 자동 레이아웃을 비활성화합니다. 내가 찾고 있던 것은 자동 레이아웃 시스템에서 하나의 특정 하위보기 만 가져 오는 방법입니다.
terriblememory
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.