방금 iOS 용 AutoLayout을 배우기 시작했고 Visual Format Language를 살펴 보았습니다.
한 가지를 제외하고는 모두 잘 작동합니다. 수퍼 뷰 내에서 중심을 볼 수는 없습니다.
VFL에서 가능합니까? 아니면 직접 구속 조건을 직접 만들어야합니까?
방금 iOS 용 AutoLayout을 배우기 시작했고 Visual Format Language를 살펴 보았습니다.
한 가지를 제외하고는 모두 잘 작동합니다. 수퍼 뷰 내에서 중심을 볼 수는 없습니다.
VFL에서 가능합니까? 아니면 직접 구속 조건을 직접 만들어야합니까?
답변:
현재 VFL 만 사용하여 수퍼 뷰에서 뷰를 중앙에 배치하는 것이 불가능한 것처럼 보이지 않습니다 . 그러나 단일 VFL 문자열과 단일 추가 제약 조건 (축당)을 사용하여 수행하는 것은 그리 어렵지 않습니다.
VFL : "|-(>=20)-[view]-(>=20)-|"
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:view.superview
attribute:NSLayoutAttributeCenterX
multiplier:1.f constant:0.f];
하나는 당신이 단순히 이것을 할 수 있다고 생각할 것입니다 (이 질문을 보았을 때 처음에 생각하고 시도한 것입니다).
[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=20)-[view(==200)]-(>=20)-|"
options: NSLayoutFormatAlignAllCenterX | NSLayoutFormatAlignAllCenterY
metrics:nil
views:@{@"view" : view}];
위의 변형을 내 의지에 구부리려고 여러 가지 변형을 시도했지만 두 축 ( H:|V:
)에 대해 두 개의 별도 VFL 문자열이 명시 적으로있는 경우에도 슈퍼 뷰에 적용되지 않는 것으로 보입니다 . 그런 다음 옵션 이 VFL에 적용될 때 정확하게 시도하고 격리하기 시작했습니다 . VFL의 수퍼 뷰 에는 적용 되지 않는 것으로 보이며 VFL 문자열에 언급 된 명시 적 뷰에만 적용됩니다 (일부 경우 실망).
앞으로 애플은 VFL의 슈퍼 뷰 외에 단 하나의 명시적인 뷰만있을 때만 VFL 옵션이 슈퍼 뷰를 고려할 수있는 새로운 옵션을 추가하기를 희망합니다. 또 다른 해결책은 VFL로 전달되는 다른 옵션이 될 수 있습니다 NSLayoutFormatOptionIncludeSuperview
.
말할 필요도없이, 나는 VFL에 대해이 질문에 대답하려고 많은 것을 배웠습니다.
|
하고 [superview]
별도의 내부 엔티티로 사용 하기 때문에 작동 합니다. 을 사용하여 [superview]
자동 레이아웃은 정렬 메트릭에 superview 객체를 포함시킵니다 (github 링크의 답변에서 NSLayoutFormatAlignAllCenterY
/ X
메트릭).
예. Visual Format Language를 사용하여 슈퍼 뷰에서 뷰를 중앙에 배치 할 수 있습니다. 수직 및 수평 모두. 데모는 다음과 같습니다.
제약 조건을 수동으로 만드는 것이 좋습니다.
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
이제 NSLayoutAnchor 를 사용 하여 AutoLayout을 프로그래밍 방식으로 정의 할 수 있습니다 .
(iOS 9.0 이상에서 사용 가능)
view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
iOS와 macOS에서 자동 레이아웃을 쉽게하기 위해 DSL 인 SnapKit을 사용하는 것이 좋습니다 .
view.snp.makeConstraints({ $0.center.equalToSuperview() })
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.
절대적으로 다음과 같이 할 수있었습니다.
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-(<=1)-[subview]"
options:NSLayoutFormatAlignAllCenterY
metrics:nil
views:NSDictionaryOfVariableBindings(view, subview)];
여기 에서 이것을 배웠 습니다. 위의 코드는 분명히 Y에 의해 하위 뷰를 볼 수 있습니다.
스위프트 3 :
NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=1)-[subview]",
options: .alignAllCenterY,
metrics: nil,
views: ["view":self, "subview":_spinnerView])
아래 코드를 추가하고 버튼을 화면 중앙에 두십시오. 물론 가능합니다.
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[button]-|"
options:NSLayoutFormatAlignAllCenterY
metrics:0
views:views]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[button]-|"
options:NSLayoutFormatAlignAllCenterX
metrics:0
views:views]];
@Evgenii의 답변 덕분에 요지에서 전체 예제를 만듭니다.
맞춤 높이로 빨간색 정사각형을 세로로 가운데에 맞 춥니 다.
https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626
직관적이지 않은 VFL을 사용하거나 구속 조건을 수동으로 사용하여 뷰를 세로로 가운데에 맞출 수 있습니다. 그건 그렇고, VFL에서 centerY와 height를 함께 결합 할 수 없습니다 :
"H:[subView]-(<=1)-[followIcon(==customHeight)]"
현재 솔루션에서 VFL 제약 조건이 별도로 추가되었습니다.
추가보기를 사용할 수 있습니다.
NSDictionary *formats =
@{
@"H:|[centerXView]|": @0,
@"V:|[centerYView]|": @0,
@"H:[centerYView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterY),
@"V:[centerXView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterX),
};
NSDictionary *views = @{
@"centerXView": centerXView,
@"centerYView": centerYView,
@"yourView": yourView,
};
^(NSString *format, NSNumber *options, BOOL *stop) {
[superview addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:format
options:options.integerValue
metrics:nil
views:views]];
}];
깔끔하게하려면 centerXView.hidden = centerYView.hidden = YES;
.
추신 : 영어가 제 2 언어이기 때문에 여분의 뷰를 "자리 표시 자"라고 부를 수 있는지 확실하지 않습니다. 누군가 저에게 말해 줄 수 있다면 감사하겠습니다.
Interface Builder
기반 솔루션을 위해 여기에 온 사람들 (Google이 여기로 안내합니다)의 경우 const width / height 제약 조건을 추가하고 하위보기-> 컨트롤 드래그로 슈퍼 뷰로 이동-> "수직 뷰에서 가로 / 세로 중심"을 선택하십시오.
//create a 100*100 rect in the center of superView
var consts = NSLayoutConstraint.constraints(withVisualFormat: "H:|-space-[myView]-space-|", options: [], metrics:["space":view.bounds.width/2-50], views:["myView":myView])
consts += NSLayoutConstraint.constraints(withVisualFormat: "V:|-space-[myView]-space-|", options: [], metrics: ["space":view.bounds.height/2-50], views: ["myView":myView])
스위프트 2의 @ igor-muzyka 답변 :
NSLayoutConstraint.constraintsWithVisualFormat("H:[view]-(<=1)-[subview]",
options: .AlignAllCenterY,
metrics: nil,
views: ["view":view, "subview":subview])