Programming

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

procodes 2020. 8. 15. 13:51
반응형

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


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

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


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

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

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

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

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


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


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

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

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

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


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

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];
}];

도움이되기를 바랍니다.


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


  • 4.5에서 프로젝트 열기
  • 스토리 보드 선택
  • Open the file inspector
  • Under Interface Builder Document uncheck 'Use Autolayout'

You can split across multiple storyboards if you want to use autolayout for some views.


For me it worked to create the subview programmatically, in my case the auto layout was messing with a view that I needed to rotate around its center but once I created this view programmatically it worked.


In my view I had a Label and a Text. The label had pan gesture. The label moves around fine during drag. But when I use the text box keyboard, the label resets its position to the original location defined in auto layout. The issue got resolved when I added the following in swift for the label. I added this in viewWillAppear but it can be added pretty much anywhere you have access to the target field.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

This happened to me in a project without storyboards or xib files. All 100% code. I had an ad banner at the bottom and wanted the view bounds to stop at the ad banner. The view would resize itself automatically after loading. I tried every resolution on this page but none of them worked.

I ended up just creating a sub view with the shortened height and placed that in into the main view of the controller. Then all my content went inside the sub view. That solved the problem very easily without doing anything that felt like it was going against the grain.

I am thinking if you want a view that is not the normal size that fills the window then you should use a sub view for that.


I've encountered a similar scenario, where I joined a project that was initiated with auto-layout, but I needed to make dynamic adjustments to several views. Here is what has worked for me:

  1. Do NOT have views or components laid out in interface builder.

  2. Add your views purely programmatically starting with alloc/init and setting their frames appropriately.

  3. Done.


Instead of disabling autolayout, I would just calculate the new constraint with the frame you are replacing. That appears to me to be the appropriate way. If you are adjusting components that rely on constraints, adjust them accordingly.

For example, if you have a vertical constraint of 0 between two views (myView and otherView), and you have a pan gesture or something that adjusts the height of myView then you can recalculate the constraint with the adjusted values.

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

For those of you who are using auto layout, please check out my solution here. You should be making @IBOutlet's of the constraints you want to adjust and then change their constants.


if it's xib file:

  1. select the .xib file
  2. select the "File's Owner"
  3. show the Utilities
  4. click on: "File Inspector"
  5. Under "Interface Builder Document" disable: "Use Autolayout"

참고URL : https://stackoverflow.com/questions/11368440/can-i-disable-autolayout-for-a-specific-subview-at-runtime

반응형