프로그래밍 방식으로 CenterX / CenterY 제약 추가
표시 할 항목이 없으면 섹션을 표시하지 않는 UITableViewController가 있습니다. 이 코드로 표시 할 항목이 없음을 사용자에게 알리기 위해 레이블을 추가했습니다.
label = UILabel(frame: CGRectMake(20, 20, 250, 100))
label.text = "Nothing to show"
self.tableView.addSubview(label)
하지만 지금은 수평 및 수직으로 중앙에 위치하기를 원합니다. 일반적으로 스크린 샷에서 강조 표시된 두 가지 옵션 (높이 및 너비에 대한 옵션 포함)을 선택합니다.
제약 조건을 추가하기 위해 다음 코드를 시도했지만 앱이 오류와 함께 충돌합니다.
label = UILabel(frame: CGRectMake(20, 20, 250, 100))
label.text = "Nothing to show"
let xConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterY, multiplier: 1, constant: 0)
label.addConstraint(xConstraint)
label.addConstraint(yConstraint)
오류:
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2014-12-23 08:17:36.755 [982:227877] *** Assertion failure in -[UILabel _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /SourceCache/UIKit/UIKit-3318.16.21/NSLayoutConstraint_UIKitAdditions.m:560
앱이 기기 회전을 지원하므로 라벨은 항상 가로 및 세로 중앙에 있어야합니다.
내가 도대체 뭘 잘못하고있는 겁니까? 이러한 제약 조건을 어떻게 성공적으로 추가합니까?
감사!
Swift 3 / Swift 4 업데이트 :
iOS 8부터는 isActive
속성을 로 설정하여 제약 조건을 활성화 할 수 있으며 활성화해야 합니다 true
. 이를 통해 제약 조건이 적절한 뷰에 추가 될 수 있습니다. 제약 조건을 포함하는 배열을 전달하여 한 번에 여러 제약 조건을 활성화 할 수 있습니다.NSLayoutConstraint.activate()
let label = UILabel(frame: CGRect.zero)
label.text = "Nothing to show"
label.textAlignment = .center
label.backgroundColor = .red // Set background color to see if label is centered
label.translatesAutoresizingMaskIntoConstraints = false
self.tableView.addSubview(label)
let widthConstraint = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal,
toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 250)
let heightConstraint = NSLayoutConstraint(item: label, attribute: .height, relatedBy: .equal,
toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 100)
let xConstraint = NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: self.tableView, attribute: .centerX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: self.tableView, attribute: .centerY, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([widthConstraint, heightConstraint, xConstraint, yConstraint])
더 나은 솔루션 :
이 질문에 대한 답변이 원래 있었기 때문에 레이아웃 앵커가 도입되어 제약 조건을 훨씬 쉽게 만들 수 있습니다. 이 예에서는 제약 조건을 만들고 즉시 활성화합니다.
label.widthAnchor.constraint(equalToConstant: 250).isActive = true
label.heightAnchor.constraint(equalToConstant: 100).isActive = true
label.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor).isActive = true
또는 다음을 사용하여 동일 NSLayoutConstraint.activate()
:
NSLayoutConstraint.activate([
label.widthAnchor.constraint(equalToConstant: 250),
label.heightAnchor.constraint(equalToConstant: 100),
label.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor)
])
참고 : 제약 조건을 만들고 활성화 하기 전에 항상 하위 뷰를 뷰 계층 구조에 추가하십시오 .
원래 답변 :
제약 조건은 self.tableView
. 레이블을의 하위보기로 추가하고 self.tableView
있으므로 제약 조건을 "공통 조상"에 추가해야합니다.
self.tableView.addConstraint(xConstraint)
self.tableView.addConstraint(yConstraint)
@mustafa 및 @kcstricks는 의견에서 지적한 것처럼, 당신은 설정해야 label.translatesAutoresizingMaskIntoConstraints
하는 false
. 이렇게하면 프레임이 더 이상 사용되지 않기 때문에 제약 조건이있는 레이블 width
및 의도 지정해야합니다 height
. 마지막으로, 당신은 또한 설정해야합니다 textAlignment
에 .Center
텍스트가 레이블에 중앙에 오도록.
var label = UILabel(frame: CGRectZero)
label.text = "Nothing to show"
label.textAlignment = .Center
label.backgroundColor = UIColor.redColor() // Set background color to see if label is centered
label.translatesAutoresizingMaskIntoConstraints = false
self.tableView.addSubview(label)
let widthConstraint = NSLayoutConstraint(item: label, attribute: .Width, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 250)
label.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: label, attribute: .Height, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100)
label.addConstraint(heightConstraint)
let xConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterY, multiplier: 1, constant: 0)
self.tableView.addConstraint(xConstraint)
self.tableView.addConstraint(yConstraint)
컨테이너 중앙
아래 코드는 Interface Builder에서 센터링과 동일한 작업을 수행합니다.
override func viewDidLoad() {
super.viewDidLoad()
// set up the view
let myView = UIView()
myView.backgroundColor = UIColor.blue
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add code for one of the constraint methods below
// ...
}
방법 1 : 앵커 스타일
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
방법 2 : NSLayoutConstraint 스타일
NSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true
메모
- Anchor style is the preferred method over
NSLayoutConstraint
Style, however it is only available from iOS 9, so if you are supporting iOS 8 then you should still useNSLayoutConstraint
Style. - You will also need to add length and width constraints.
- My full answer is here.
The ObjectiveC equivalent is:
myView.translatesAutoresizingMaskIntoConstraints = NO;
[[myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] setActive:YES];
[[myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] setActive:YES];
Programmatically you can do it by adding the following constraints.
NSLayoutConstraint *constraintHorizontal = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:attribute
multiplier:1.0f
constant:0.0f];
NSLayoutConstraint *constraintVertical = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:attribute
multiplier:1.0f
constant:0.0f];
If you don't care about this question being specifically about a tableview, and you'd just like to center one view on top of another view here's to do it:
let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: parentView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
parentView.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: parentView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
parentView.addConstraint(verticalConstraint)
In Swift 5 it looks like this:
label.translatesAutoresizingMaskIntoConstraints = false
label.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true
A solution for me was to create a UILabel
and add it to the UIButton
as a subview. Finally I added a constraint to center it within the button.
UILabel * myTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 75, 75)];
myTextLabel.text = @"Some Text";
myTextLabel.translatesAutoresizingMaskIntoConstraints = false;
[myButton addSubView:myTextLabel];
// Add Constraints
[[myTextLabel centerYAnchor] constraintEqualToAnchor:myButton.centerYAnchor].active = true;
[[myTextLabel centerXAnchor] constraintEqualToAnchor:myButton.centerXAnchor].active = true;
참고 URL : https://stackoverflow.com/questions/27624133/programmatically-add-centerx-centery-constraints
'Development Tip' 카테고리의 다른 글
jQuery로 HTML 주석 선택 (0) | 2020.11.07 |
---|---|
C #의 부분 클래스는 잘못된 디자인입니까? (0) | 2020.11.07 |
ASP.NET MVC 3-다른 작업으로 리디렉션 (0) | 2020.11.06 |
System.Windows.Forms를 사용할 수 없습니다. (0) | 2020.11.06 |
CREATE FILE에서 운영 체제 오류 5가 발생했습니다 (이 오류에 대한 텍스트를 검색하지 못했습니다. 이유 : 15105). (0) | 2020.11.06 |