Visual Format Language를 사용하여 슈퍼 뷰에서 뷰 중심 맞추기
방금 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에 대해이 질문에 대답하려고 많은 것을 배웠습니다.
예, Visual Format Language를 사용하여 슈퍼 뷰에서 뷰를 중앙에 배치 할 수 있습니다. 수직 및 수평 모두. 데모는 다음과 같습니다.
https://github.com/evgenyneu/center-vfl
제약 조건을 수동으로 만드는 것이 좋습니다.
[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() })
절대적으로 다음과 같이 할 수있었습니다.
[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]];
I know it's not want you want but you can of course calculate the margins and use them to create the visual format string ;)
Anyway, no. Unfortunatly it's not possible to do that 'automatically' with VFL - at least not yet.
Thanks to the answer from @Evgenii, I create a full example in gist:
center the red square vertically with custom height
https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626
You can center a view vertically by useing either VFL (which is not quite intuitive) or use constraints manually. By the way, I cannot combine both centerY and height together in VFL like:
"H:[subView]-(<=1)-[followIcon(==customHeight)]"
In the current solution VFL constraints are added separately.
What it have to be done is that superview should be declared in the dictionary. Instead of using |
you use @{@"super": view.superview};
.
And NSLayoutFormatAlignAllCenterX
for vertical and NSLayoutFormatAlignAllCenterY
for horizontal as options.
You can use extra views.
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]];
}];
If you want it neat, then centerXView.hidden = centerYView.hidden = YES;
.
PS: I am not sure I can call the extra views "placeholders", because English is my second language. It will be appreciated if someone can tell me that.
For those who came here for an Interface Builder
based solution (Google leads me here), just add const width/height constraints, and select the subview -> control drag to it's superview -> select "center vertically/horizontally in superview".
Just need to say, that u can use this instead of constraints:
child.center = [parent convertPoint:parent.center fromView:parent.superview];
@igor-muzyka answer in Swift 2:
NSLayoutConstraint.constraintsWithVisualFormat("H:[view]-(<=1)-[subview]",
options: .AlignAllCenterY,
metrics: nil,
views: ["view":view, "subview":subview])
Instead of using VFL, you can easily do this in interface builder. In the Main Storyboard, ctrl+click on the view you want to center. Drag to the superview (while holding ctrl) and select "Center X" or "Center Y". No code needed.
'IT story' 카테고리의 다른 글
ActiveRecord :: Base를 확장하는 레일 (0) | 2020.06.03 |
---|---|
UITextField 비밀번호를 숨 깁니다. (0) | 2020.06.03 |
프로그래밍 방식으로 ID 열 값을 변경하는 방법은 무엇입니까? (0) | 2020.06.02 |
SQL Logic Operator Precedence : And and Or (0) | 2020.06.02 |
Windows 라이브러리의 내용을 보는 방법 (* .lib) (0) | 2020.06.02 |