IT story

자동 레이아웃 제약 조건을 사용할 때 뷰의 현재 너비와 높이를 어떻게 얻을 수 있습니까?

hot-time 2020. 8. 18. 08:18
반응형

자동 레이아웃 제약 조건을 사용할 때 뷰의 현재 너비와 높이를 어떻게 얻을 수 있습니까?


나는 프레임 속성에 대해 말하는 것이 아닙니다. 그로부터 당신은 xib에서 뷰의 크기를 얻을 수 있기 때문입니다. 제약 조건 (회전 후 또는 이벤트에 대한 응답으로)으로 인해 뷰의 크기가 조정되는시기에 대해 이야기하고 있습니다. 현재 너비와 높이를 얻는 방법이 있습니까?

너비 및 높이 제약 조건을 찾기 위해 제약 조건을 반복하려고 시도했지만 내부 제약 조건이있을 때 매우 깨끗하지 않고 실패합니다 (둘을 구분할 수 없기 때문에). 또한 실제로 너비 및 높이 제한이있는 경우에만 작동하며 크기를 조정하기 위해 다른 제한에 의존하는 경우에는 작동하지 않습니다.

이게 왜 그렇게 어려운가요? ARG!


대답은 [view layoutIfNeeded]입니다.

그 이유는 다음과 같습니다.

view.bounds.size.widthview.bounds.size.height(또는을 사용하지 않는 한 동일한 프레임)을 검사하여 뷰의 현재 너비와 높이를 여전히 얻습니다 view.transform.

원하는 것이 기존 제약 조건에 의해 암시 된 너비와 높이 인 경우 자동 레이아웃 시스템의 전체 제약 해결 논리를 다시 구현해야하므로 제약 조건을 수동으로 검사하지 않는 것이 좋습니다. 대신해야 할 일은 자동 레이아웃에 해당 레이아웃을 업데이트하도록 요청 하여 제약 조건을 해결하고 올바른 솔루션으로 view.bounds 값을 업데이트 한 다음 view.bounds를 검사하는 것입니다.

레이아웃 업데이트를 위해 자동 레이아웃을 어떻게 요청합니까? [view setNeedsLayout]자동 레이아웃이 런 루프의 다음 턴에 레이아웃을 업데이트하도록하려면 호출 하십시오.

그러나 레이아웃을 즉시 업데이트하여 나중에 현재 함수 내에서 또는 실행 루프가 시작되기 전 다른 지점에서 새 경계 값에 즉시 액세스 할 수 있도록하려면[view setNeedsLayout]을 호출해야합니다 [view layoutIfNeeded].

두 번째 질문 : "직접 참조가없는 경우 높이 / 너비 제약 조건을 어떻게 변경할 수 있습니까?"

IB에서 제약 조건을 생성하는 경우 최상의 솔루션은 뷰 컨트롤러 또는 뷰에 IBOutlet을 생성하여 직접 참조 할 수 있도록하는 것입니다. 코드에서 제약 조건을 만든 경우에는 만들 때 내부 약한 속성의 참조를 유지해야합니다. 다른 사람이 제약 조건을 생성 한 경우 뷰의 view.constraints 속성과 전체 뷰 계층 구조를 검사하고 중요한 NSLayoutConstraint를 찾는 논리를 구현하여이를 찾아야합니다. 이 질문에 대한 간단한 대답이 보장되지 않을 때 경계 크기를 결정한 특정 제약 조건을 효과적으로 결정해야하기 때문에 잘못된 방법 일 수 있습니다. 최종 경계 값은 여러 제약 조건의 매우 복잡한 시스템에 대한 솔루션이 될 수 있습니다.


UITableView.NET Framework의 제약 조건 설정에 따라 크기가 조정 되는에 위쪽 및 아래쪽 테두리를 추가해야하는 비슷한 문제가있었습니다 UIStoryboard. 을 사용하여 업데이트 된 제약 조건에 액세스 할 수있었습니다 - (void)viewDidLayoutSubviews. 이것은 뷰를 서브 클래 싱하고 레이아웃 메서드를 재정의 할 필요가 없도록 유용합니다.

/*** SET TOP AND BOTTOM BORDERS ON TABLE VIEW ***/
- (void)addBorders
{
    CALayer *topBorder           = [CALayer layer];
    topBorder.frame              = CGRectMake(0.0f, self.tableView.frame.origin.y, 320.0f, 0.5f);
    topBorder.backgroundColor    = [UIColor redColor].CGColor;

    CALayer *bottomBorder        = [CALayer layer];
    bottomBorder.frame           = CGRectMake(0.0f, (self.tableView.frame.origin.y + self.tableView.frame.size.height), 320.0f, 0.5f);
    bottomBorder.backgroundColor = [UIColor redColor].CGColor;

    [self.view.layer addSublayer:topBorder];
    [self.view.layer addSublayer:bottomBorder];
}

/*** GET AUTORESIZED FRAME DIMENSIONS ***/
- (void)viewDidLayoutSubviews{
    [self addBorders];
}

메서드에서 메서드를 호출하지 않으면 viewDidLayoutSubview아래쪽 테두리가 화면 밖의 어딘가에 있으므로 위쪽 테두리 만 올바르게 그려집니다.


특히 TableviewCell을 사용하여 여전히 이러한 문제에 직면 할 수있는 사람들을 위해.

메소드를 재정의하십시오.

-(void)layoutSubviews
{
//your code here like drawing a shadow
}

UITableViewCell 또는 UICollectionViewCell의 경우 셀의 하위 클래스를 만들고 동일한 메서드를 재정의합니다.

-(void)layoutSubviews
{
//your code here like drawing a shadow
}

사용 -(void)viewWillAppear:(BOOL)animated및 전화 [self.view layoutIfNeeded];-내가 시도한 작동합니다.

because if you use -(void)viewDidLayoutSubviews it will work definitely but this method is called every time your UI demands updations/changes. Which will get hard to manage. Soft key is you use a bool variable to avoid such loop of calls. better use viewWillAppear. Remember viewWillAppear will also be called if view is loaded back again (without reallocating).


The frame is still valid. In the end, the view uses its frame property to lay itself out. It calculates that frame based on all the constraints. The constraints are only used for the initial layout (and any time layoutSubviews is called on a view like after a rotation). After that, the position info is in the frame property. Or are you seeing otherwise?

참고URL : https://stackoverflow.com/questions/13446920/how-can-i-get-a-views-current-width-and-height-when-using-autolayout-constraint

반응형