Program Club

같은 뷰에서 setFrame과 autolayout을 사용할 수 있습니까?

proclub 2020. 11. 25. 21:26
반응형

같은 뷰에서 setFrame과 autolayout을 사용할 수 있습니까?


모든 버튼에 패딩을 추가하고 싶기 때문에 UIButton을 서브 클래 싱하고 다른 변경 사항 중에서 setFrame 메서드를 사용하여 고정 패딩을 추가하고 싶었습니다. setFrame을 제외한 모든 것이 작동했습니다. 주변을 확인한 결과 해당 뷰에서 "AutoLayout 사용"을 선택 취소하면 setFrame을 사용할 수 있으며 작동한다는 것을 알았습니다. 이 문제를 해결할 방법이 있습니까? 자동 레이아웃을 사용하면 iPhone 5 및 이전 기기에서 앱이 멋지게 보이도록하는 데 도움이되므로 정말 사용하고 싶습니다. 그러나 나는 또한 내 삶을 더 쉽게 만들기 위해 내 하위 클래스에서 setFrame을 사용하고 싶습니다.

요약하면 내 질문은 자동 레이아웃을 사용하고 프로그래밍 방식으로 UIView의 프레임을 조정할 수 있습니까?


네, 가능합니다.

뷰의를 설정하면에 대한 translatesAutoresizingMaskIntoConstraints = YES호출 setFrame:은 런타임시 뷰의 현재를 기반으로 레이아웃 제약 조건으로 자동 변환됩니다 autoresizingMask. 이를 통해 프레임 기반 레이아웃과 제약 기반 레이아웃을 혼합 할 수 있습니다.

예를 들어 자동 레이아웃을 사용하여 뷰의 모든 하위 뷰의 레이아웃을 정의 할 수 있지만 여전히 setFrame:뷰 자체의 크기와 위치를 설정하려면 호출 합니다. 당신의 관점에서, 당신은 자동 레이아웃과 직접 프레임 조작이 혼합 된 레이아웃을하고 있습니다. 그러나 시스템은 실제로 모든 것을 처리하기 위해 제약 조건을 사용하고 있습니다.

그러나 translatesAutoresizingMaskIntoConstraints.

이 작업을 수행 할 때 이러한 자동 제약 조건이 나머지 제약 조건을 만족할 수 있는지 확인해야합니다 .

그래서, 예를 들어,이보기의 크기와 위치를 결정 제약 조건이 이미 한 다음 가정 설정 translatesAutoresizingMaskIntoConstraints = YES및 호출 setFrame:. 를 호출 setFrame:하면 뷰에 새로운 제약 조건이 생성되며, 이는 이미 존재하는 제약 조건과 충돌 할 수 있습니다.

(사실이 오류는 자주 발생합니다. 충돌하는 제약 조건에 대해 불평하는 로그 메시지를 본 적이 있고 이러한 제약 조건 중 하나 NSAutoresizingMaskLayoutConstraint가이면 표시되는 것은 자동 제약 조건과의 충돌입니다. 이것은 쉬운 실수입니다. translatesAutoresizingMaskIntoConstraints = YES기본 값이므로 코드에서 제약 조건을 구성하는 경우 이러한 자동 제약 조건을 원하지 않으면 해제해야합니다.)

반대로 뷰의 크기와 위치를 결정하는 기존 제약 조건이 이미 존재하지만을 translatesAutoresizingMaskIntoConstraints = NO호출하기 전에 설정했다고 가정합니다 setFrame:. 이 경우 setFrame:호출은 새로운 제약 조건을 생성하지 않으므로 별도의 제약 조건간에 충돌이 발생하지 않습니다 . 그러나이 경우 제약 조건과 설정 한 프레임 값 사이에 여전히 "충돌" 이 있습니다 . 다음에 자동 레이아웃이 호출되면 뷰에 이미 존재하는 제약 조건이 표시되고 필요한 프레임 값을 계산하고 프레임을 필요한 값 자체로 설정하여 수동으로 설정 한 값을 막습니다.

자세한 내용은 Apple의 Cocoa Auto Layout Guide 의 "Adopting Auto Layout"섹션을 확인하십시오 .


가장 쉬운 방법은 수퍼 뷰에서 이동 / 크기 조정하려는 뷰를 제거하고을 설정 frame한 다음 다시 추가하는 것이 었습니다. 예를 들어, 하위 클래스 UILabel에서 사용자 정의 를 가져 UITableViewCell옵니다.

[cell.myLabel removeFromSuperview];
cell.myLabel.frame = someFrameIGenerated;
[cell.contentView addSubview:cell.myLabel];

나를 위해 일한 것은 단순히 IBOutlet뷰 컨트롤러에 대한 제약 조건을 추가 한 다음 constant콘센트 속성 을 변경하는 것 입니다.

예를 들어, 뷰의 x 원점을 변경하려면 해당 뷰의 선행 제약 조건에서 컨트롤러에 대한 콘센트를 설정합니다. 즉, 콘센트를 만듭니다 @IBOutlet var labelXOrigin: NSLayoutConstraint!. 그런 다음 x 위치를 조정하려면 다음과 같이하십시오.

self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set.

하위 뷰의 프레임을 설정하는 가장 좋은 방법은 자동 레이아웃 프로젝트의 viewWillLayoutSubviews 메서드입니다.

set property translateAutoresizingMaskIntoConstraints = true 이것은 뷰가 나타난 후에 작동하거나 뷰가 나타난 직후에 버튼을 눌러 설정합니다.


앱이 여러 기기 방향을 지원하지 않는 경우.

있는 viewDidLoad 크기를 조정할 뷰의 프레임을 설정

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [aView setFrame:CGRectMake(15, 15, 100, 100)];
}

그런 다음 viewDidLayoutSubviews에서 :

-(void)viewDidLayoutSubviews
{
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

잘 모르겠지만이 솔루션을 사용하면 한 방향을 다른 방향으로 전환하면 문제가 발생할 수 있다고 생각합니다.

참고 URL : https://stackoverflow.com/questions/13186908/can-i-use-setframe-and-autolayout-on-the-same-view

반응형