자동 레이아웃을 사용하여 하위보기가 동적으로 변경된 후 superview 크기 조정


83

나는 신의 사랑이 크기 조정 슈퍼 뷰의 요령을 참을 수 없다.

나는 UIView *superview 4를 가지고 있습니다 UILabels. 2는 다른 2 명의 헤더 역할을합니다.

4 개의 콘텐츠는 모두 데이터베이스에서 동적으로 제공됩니다.

SizeToFitvs SizeThatFits:(CGSize)vs UIView systemLayoutSizeFittingSize:, UILayoutFittingCompressedSize또는 UILayoutFittingExpandedSize.

나는 자동 레이아웃을 프로그래밍 방식으로 사용하고 슈퍼 뷰 높이를 더미 숫자와 같거나 더 크게 설정했습니다.

어디서 어떻게 나는이 사용합니까 SizeToFitsizeThatFits:(CGSize)UIView systemLayoutSizeFittingSize:중 하나를 통과, UILayoutFittingCompressedSize또는 UILayoutFittingExpandedSize. 여기 스택에 대한 많은 팁을 읽었지만 아무것도 얻지 못했습니다.

특정 어딘가에서 superview에 대한 제약 조건을 다시 계산해야합니까? Maby는 컨트롤러 클래스에서 '@property'로 높이를 설정하고 제거하고 읽었습니까? Atm 나는 모든 곳에 모든 것을 넣은 다음 일부를 시도했습니다. 그래도 더미 높이와 텍스트가 외부에 떠있는 동일한 크기의 최종 결과를 얻습니다. 하위보기에서 clipsToBound를 설정 한 후에도.

머리를 긁고 있어요 .. help


1
이봐 요, 제가 살펴볼 수 있다면 당신의 코드를 pastebin 어딘가에 게시 할 수 있습니까? 나는 비슷한 문제로 고통 받고 있습니다. 일주일 이상이 지났습니다.
esh

답변:


104

자동 레이아웃을 사용하는 경우 수행해야 할 작업은 다음과 같습니다.

  1. 동적으로 크기를 조정하려는 치수에 따라 하위보기에 고정 너비 및 / 또는 높이 제약 조건을 추가하고 있지 않은지 확인합니다. 아이디어는 각 하위보기의 고유 콘텐츠 크기가 하위보기의 높이를 결정하도록하는 것입니다. UILabel에는 4 개의 자동 암시 적 제약이있어 (필수 우선 순위보다 낮음) 라벨의 프레임을 내부의 모든 텍스트에 맞추는 데 필요한 정확한 크기로 유지하려고 시도합니다.

  2. 각 레이블의 가장자리가 서로의 가장자리와 수퍼 뷰에 단단히 연결되어 있는지 확인합니다 (필수 우선 순위 제약 조건 포함). 레이블 중 하나의 크기가 커지는 것을 상상하면 다른 레이블이이를위한 공간을 확보하고 가장 중요한 것은 수퍼 뷰도 확장되도록 강제합니다.

  3. 크기가 아닌 위치를 설정하려면 수퍼 뷰에만 제약 조건을 추가하십시오 (적어도 동적 크기 조정을 원하는 차원에는 해당되지 않음). 내부 제약 조건을 올바르게 설정하면 가장자리가 어떤 방식 으로든 가장자리가 연결되어 있기 때문에 모든 하위보기의 크기에 따라 크기가 결정됩니다.

그게 다야. 당신은 호출 할 필요는 없습니다 sizeToFit또는 systemLayoutSizeFittingSize:작업이를 얻기 위해, 당신의 의견을로드하고 텍스트를 설정하고 그것을해야합니다. 시스템 레이아웃 엔진은 제약 조건을 해결하기 위해 계산을 수행합니다. (무엇이든 setNeedsLayout수퍼 뷰 를 호출해야 할 수도 있지만 ... 필수는 아닙니다.)


감사합니다 smileyborg. 프로젝트를 진행하던 중 늦게 응답했지만 멘션을받지 못했습니다. 이제 프로그래밍 방식으로 그리고 특히 제약 조건으로 좀 더 작업 할 수있는 기회를 얻었 constraintsWithVisualFormat으며 포함 하위 뷰가
늘어나고

내가 솔루션에 동의하지만, 나를 위해 작동하지 않습니다 확인 stackoverflow.com/questions/34635838/...을
오메르

이 대답은 마술입니다. 보기를 좋게 보이게 만드는 내 부분의 노력이 훨씬 적습니다.
크리스

1
translatesAutoresizingMaskIntoConstraints = NOxib를 사용하는 경우 설정해야한다고 언급해야합니다 .
KudoCC

translatesAutoresizingMaskIntoConstraints = NO가 제 경우에 대한 대답입니다. 하지만 이제 컨테이너 뷰는 프레임을 잃고 원점은 항상 (0,0)이므로 원하는 위치에 놓을 수 없습니다. stackoverflow.com/questions/45548372/…
karim

24

컨테이너보기 사용

다음 예제에는 30x30 이미지가 있고은 UILabel자리 표시 자 텍스트가있는 포함보기보다 작습니다. 컨테 이닝 뷰는 적어도 이미지만큼 커야했지만 여러 줄 텍스트를 포함하려면 커야했습니다.

시각적 형식에서 내부 컨테이너는 다음과 같습니다.

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

그런 다음 레이블의 높이와 일치하도록 컨테이너 뷰를 설정합니다. 이제 컨테 이닝 뷰가 레이블의 크기를 차지합니다.

@smileyborg가 그의 답변에서 지적했듯이 콘텐츠를 superview에 엄격하게 연결하면 레이아웃 엔진에 간단한 컨테이너 뷰로 인해 성장해야 함을 알립니다.

노란색 정렬 직사각형

노란색 정렬 사각형을 원하면 -UIViewShowAlignmentRects YES계획의 실행 인수 목록에 추가 하십시오.

여러 줄로 된 UILabel


12
-UIViewShowAlignmentRects YES-훌륭한 팁!
Ralfonso 2015 년

2
이 경우 컨테이너는 높이를 라벨에 맞추기 만하면됩니다. 컨테이너가 둘 이상의 뷰 높이 합계에 적응해야하는 경우 어떻게됩니까?
da Rocha Pires

7

이것은 iOS 9의 스택 뷰 도입으로 훨씬 더 쉬워졌습니다. 뷰 내부에 스택 뷰를 사용하여 크기가 조정되는 모든 콘텐츠를 포함하고 다음을 호출하기 만하면됩니다.

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

콘텐츠를 변경 한 후. 그런 다음 전화하여 새 크기를 얻을 수 있습니다.

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

보기에 필요한 정확한 크기를 계산해야하는 경우.


2
내가 StackView를 사용하여 동적 뷰를 추가하고, 이러한 뷰는 크기가 조정되지 않아요 @ JacobRuth.
Mansuu ....

6

이것은 @smileyborg 대답을 거의 따르고 구체적인 예와 함께 제공됩니다.

여기에 이미지 설명 입력

모든 제약 조건을 설명하지는 않지만 UI 개체의 높이 계산과 관련된 제약 조건을 설명합니다.

  1. [레이블] 레이블에는 고정 된 height제약 조건 이 없어야합니다 .이 경우 AutoLayout은 텍스트에 맞게 레이블 크기를 조정하지 않으므로 가장자리 제약 조건을 설정하는 것이 핵심입니다. (녹색 화살표)
  2. [Subview] 1 단계와 3 단계는 따르기 쉽지만이 단계는 오해 할 수 있습니다. 레이블의 경우와 마찬가지로 하위 뷰에는 height제약 조건이 설정되어 있지 않아야합니다 . 모든 하위 뷰에는 top제약 조건을 무시하고 bottom제약 조건이 설정되어 있어야합니다.이 경우 런타임에 충족되지 않은 제약 예외가 트리거 될 것이라고 생각할 수 있지만 bottom마지막 하위 뷰에 대한 제약 조건을 설정하면 그렇지 않습니다 . 그렇게하지 않으면 레이아웃이 망가질 것입니다. (빨간색 화살표)

  3. [Superview] 모든 제약을 원하는 방식으로 설정하되 height제약에 큰주의를 기울이십시오 . 임의의 값을 할당하지만 선택 사항으로 만들면 AutoLayout은 하위 뷰에 맞게 높이를 정확하게 설정합니다. (파란색 화살표)

이것은 완벽하게 작동하며 추가 시스템 레이아웃 업데이트 메서드를 호출 할 필요가 없습니다.


높이를 선택적으로 만드는 방법 .. iOS를 처음 사용하므로 알아낼 수 없습니다. 감사합니다
Faisal Naseer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.