Programing

Cocoa Auto Layout을 사용하여 창에서 사용자 정의보기 크기를 조정하는 방법은 무엇입니까?

lottogame 2020. 10. 29. 07:48
반응형

Cocoa Auto Layout을 사용하여 창에서 사용자 정의보기 크기를 조정하는 방법은 무엇입니까?


단일 사용자 지정보기가있는 단일 창이 있고 사용자 지정보기의 크기를 창과 함께 조정하여 언제든지 완전히 채울 수 있도록합니다. 내가 쓰면 :

NSView *contentView = [self.window contentView];
CustomView *customView = [[CustomView alloc] initWithFrame:[contentView bounds]];
[contentView addSubview:customView];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeWidth
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeWidth
        multiplier:1
        constant:0]];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeHeight
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeHeight
        multiplier:1
        constant:0]];

그러면 창에서 크기를 조정할 수 없습니다.
추가하면 :

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

그런 다음 사용자 정의보기가 나타나지 않습니다 ( drawRect:결코 호출 되지 않는 것 같습니다). 나는 다른 방법 (시각적 형식 포함)을 시도 @"|[customview]|"했지만 항상 같은 문제가 발생합니다. 이전 자동 크기 조정 시스템으로 다음을 수행 할 수 있다는 것을 알고 있습니다.

[customView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];

하지만 Cocoa Auto Layout 시스템을 사용하고 싶고, 더 복잡한 경우에 사용하고 싶습니다 (항상 창을 채우는 여러 사용자 정의 뷰와 같은).

누구든지 무엇이 잘못되었으며 내가 원하는 결과를 얻기 위해 자동 레이아웃 시스템을 어떻게 사용해야하는지 알고 있습니까?


자동 레이아웃을 사용하면 전체 창의 콘텐츠보기를 차지하도록보기를 제한하고 적절한 경우 크기를 조정할 수있는 (적어도) 세 가지 방법이 있습니다.

수퍼 뷰와 관련된 시각적 형식 제약

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

NSDictionary *views = NSDictionaryOfVariableBindings(customView);

[contentView addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|"
        options:0
        metrics:nil
        views:views]];

[contentView addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|"
    options:0
    metrics:nil
    views:views]];

가장자리에 대한 프로그래밍 제약

(위의 시각적 형식과 동일해야 함)

+ (void)addEdgeConstraint:(NSLayoutAttribute)edge superview:(NSView *)superview subview:(NSView *)subview {
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:subview
        attribute:edge
        relatedBy:NSLayoutRelationEqual
        toItem:superview
        attribute:edge
        multiplier:1
        constant:0]];
}

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

[[self class] addEdgeConstraint:NSLayoutAttributeLeft superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeRight superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeTop superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeBottom superview:contentView subview:customView];

크기에 대한 프로그래밍 제약

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeWidth
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeWidth
        multiplier:1
        constant:0]];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeHeight
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeHeight
        multiplier:1
        constant:0]];

세 번째 접근 방식은 질문에 나열된 접근 방식이며 추가 제약이있는 경우 작동하지 않을 수 있습니다. 예를 들면 다음과 같습니다.

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

원래 자동 크기 조정 마스크도 적용되어 질문에 설명 된 동작으로 이어집니다. 창 크기가 조정되지 않습니다.

Regexident에서 언급했듯이 다음을 사용할 수 있습니다.

[_window visualizeConstraints:[contentView constraints]];

자동 레이아웃을 디버깅합니다. 콘솔 출력도 확인하는 것이 좋습니다.


@Bavarious의 대답은 좋습니다. 몇 가지만 더 추가하겠습니다.

It's really important to learn to use the built in debugging support! As with much development, it is not realistic to hope that you will always get everything right on the first shot. This was a major concern with auto layout, so we put a lot of effort into debugging. Steps, briefly:

  1. Determine a view that is in the wrong place. Calling the method -[NSView _subtreeDescription] from gdb and/or passing the arguments -NSShowAllViews YES can help identify which view is wrong.
  2. Determine the constraint or constraints that is wrong or missing. -[NSLayoutConstraint constraintsAffectingLayoutForOrientation:] helps give you a smaller set of constraints to work on. -[NSWindow visualizeConstraints:] can help you see what those constraints are and you can see from that which of those isn't something you want to be there. It also will show you if your layout is ambiguous (not enough constraints).
  3. Determine where the wrong constraint came from. The Cocoa Layout template in Instruments is sort of like the Leaks instrument - it'll show you all the events in the life cycle of a constraint, like where it was created, added to a window, modified, etc. So once you know what constraint is the problem, use the search field in Instruments to filter down to just viewing that constraint, and you can see backtraces for all the lifecycle events and figure out where you did something you didn't want.

Usually the kind of question you'd post (my stuff doesn't work!) will not be enough for people to tell what's wrong, which is one of the reason's it's important to use the debugging stuff. See the WWDC 2011 session video (free for all) and docs for more on this.

Buuuuut I can actually tell what went wrong this time. :-) Before you turned off translatesAutoresizingMaskIntoConstraints, you were more constrained than you wanted to be - the width and height of your view were fixed as well, which is why the window couldn't resize. AFTER you turned it off though, you had ambiguous layout, because you hadn't fastened your view onto anything! You had said how big it should be (same as the superview), but not where it was supposed to be.

Ken

Cocoa Frameworks, primary auto layout author


You can create constraints with Layout Anchors with very easy to read format:

Swift2 code

func fit(childView: UIView, parentView: UIView) {
    childView.translatesAutoresizingMaskIntoConstraints = false
    childView.topAnchor.constraintEqualToAnchor(parentView.topAnchor).active = true
    childView.leadingAnchor.constraintEqualToAnchor(parentView.leadingAnchor).active = true
    childView.trailingAnchor.constraintEqualToAnchor(parentView.trailingAnchor).active = true
    childView.bottomAnchor.constraintEqualToAnchor(parentView.bottomAnchor).active = true
}

Use:

parrentView.addSubview(childView)
fit(childView, parentView: parrentView)

I have discovered that -drawRect: willnot get called in the event the frame rectangle is 0,0,0,0. Undesirable constraints seem to cause the frame to become 0,0,0,0.

참고URL : https://stackoverflow.com/questions/8156799/how-to-make-a-custom-view-resize-with-the-window-with-cocoa-auto-layout

반응형