प्रोग्रामेटिक रूप से सेंटरएक्स / सेंटरवाई बाधाओं को जोड़ें


84

मेरे पास एक 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

लेबल हमेशा क्षैतिज और लंबवत रूप से केंद्र में होना चाहिए क्योंकि ऐप डिवाइस के रोटेशन का समर्थन करता है।

मैं क्या गलत कर रहा हूं? मैं इन बाधाओं को सफलतापूर्वक कैसे जोड़ूं?

धन्यवाद!


2
मैं VIEWDIDLOAD में इस निर्माण कर रहा हूँ।
मारियो ए गुज़मैन

2
मैं उस पंक्ति को नहीं देखता जहाँ आप लेबल को किसी अन्य दृश्य में सबव्यू के रूप में जोड़ते हैं। यह महत्वपूर्ण है कि आप इसमें बाधा डालने से पहले ऐसा करें।
स्कॉट बेरेवोएट्स

मैं हूं: लेबल = उइलाबेल (फ्रेम: CGRectMake (20, 20, 250, 100)) label.text = "कुछ भी नहीं दिखाने के लिए" self.tableView.addSubview (लेबल)
मारियो ए गुज़मैन

जवाबों:


163

स्विफ्ट 3 / स्विफ्ट 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)

अति उत्कृष्ट। धन्यवाद।
ऐप देव गाय

1
एंकरों ने मेरे लिए काम किया- मैं आपके प्रयास की सराहना करता हूँ!
FullMetalFist

37

कंटेनर में केंद्र

यहां छवि विवरण दर्ज करें

नीचे दिया गया कोड इंटरफ़ेस बिल्डर में केंद्रित करने के समान है।

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

टिप्पणियाँ

  • एंकर स्टाइल ओवर द पसंदीदा तरीका है NSLayoutConstraint , हालांकि यह केवल iOS 9 से उपलब्ध है, इसलिए यदि आप iOS 8 का समर्थन कर रहे हैं तो आपको NSLayoutConstraintस्टाइल का उपयोग करना चाहिए ।
  • आपको लंबाई और चौड़ाई की बाधाओं को भी जोड़ना होगा।
  • मेरा पूरा जवाब यहाँ है

10

ObjectiveC समतुल्य है:

    myView.translatesAutoresizingMaskIntoConstraints = NO;

    [[myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] setActive:YES];

    [[myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] setActive:YES];

मेरे लिए सबसे अच्छा एक, धन्यवाद
फादी अबूझ

8

प्रोग्रामेटिक रूप से आप इसे निम्न बाधाओं को जोड़कर कर सकते हैं।

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


5

स्विफ्ट 5 में ऐसा दिखता है:

label.translatesAutoresizingMaskIntoConstraints = false
label.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true

1

यदि आप इस प्रश्न के बारे में विशेष रूप से एक टेबलव्यू के बारे में परवाह नहीं करते हैं, और आप बस एक दृश्य को किसी अन्य दृश्य के शीर्ष पर केन्द्रित करना चाहते हैं, तो यह करना है:

    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)

1

मेरे लिए एक समाधान UILabelयह था कि मैं इसे UIButtonएक सबव्यू के रूप में बनाऊं और जोड़ सकूं। अंत में मैंने इसे बटन के भीतर केन्द्रित करने के लिए एक अवरोध जोड़ा।

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; 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.