विजुअल फॉर्मेट लैंग्वेज का उपयोग करके अपने सुपरविजन में एक दृश्य केंद्रित करना


160

मैंने अभी iOS के लिए AutoLayout सीखना शुरू किया और विज़ुअल फॉर्मेट लैंग्वेज पर एक नज़र डाली।

यह सब एक बात को छोड़कर ठीक काम करता है: मैं सिर्फ इसके पर्यवेक्षण केंद्र के भीतर देखने के लिए नहीं मिल सकता।
क्या यह VFL के साथ संभव है या क्या मुझे स्वयं एक बाधा बनाने की आवश्यकता है?

जवाबों:


232

वर्तमान में, नहीं, ऐसा नहीं लगता है कि केवल वीएफएल का उपयोग करके पर्यवेक्षण में एक दृश्य को केंद्रित करना संभव है । हालांकि, यह मुश्किल नहीं है कि एक एकल 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 के लिए लागू किया जाता है। वे दिखाई नहीं देते वीएफएल में सुपरवाइवे पर लागू होते हैं और वे केवल उन स्पष्ट विचारों पर लागू होंगे जो वीएफएल स्ट्रिंग (कुछ मामलों में निराशाजनक) में उल्लिखित हैं।

मुझे आशा है कि भविष्य में Apple किसी तरह का नया विकल्प जोड़ता है VFL के विकल्पों को सुपरवाइवे को ध्यान में रखना, भले ही ऐसा करना तब ही हो जब वीएफएल में पर्यवेक्षक के अलावा केवल एक ही स्पष्ट दृश्य हो। एक अन्य समाधान VFL में पारित एक और विकल्प हो सकता है जो कुछ इस तरह कहता है NSLayoutFormatOptionIncludeSuperview:।

कहने की जरूरत नहीं है, मैंने इस सवाल का जवाब देने की कोशिश करने वाले वीएफएल के बारे में बहुत कुछ सीखा।


2
उस विस्तृत उत्तर के लिए धन्यवाद। हालांकि, वीएफएल का उपयोग करने का एकमात्र कारण, मुझे उन बाधाओं से छुटकारा मिल रहा है। बहुत बुरा Apple अभी तक इस का समर्थन नहीं करता है ...
क्रिश्चियन श्चोर

@larsacus क्या आप इस बारे में टिप्पणी कर सकते हैं कि नीचे दिया गया उत्तर क्यों काम करता है? यह मुझे स्टम्प्ड हो गया है।
मैट जी

8
नीचे दिए गए एवगेनी का जवाब काम करता है क्योंकि ऑटोलॉयट इंजन व्यवहार करता है |और [superview]अलग आंतरिक संस्थाओं के रूप में भले ही वे एक ही शब्दार्थ वस्तु का प्रतिनिधित्व करते हैं। उपयोग करके [superview], ऑटोलॉययट अपने संरेखण मेट्रिक्स में पर्यवेक्षी वस्तु को शामिल करता है (जीथब लिंक पर उसके उत्तर में मामले में, इसकी NSLayoutFormatAlignAllCenterY/ Xमीट्रिक)।
लार्सकस

@larsacus बहुत बढ़िया, धन्यवाद!
मैट जी

क्या हम जानते हैं कि अगर अभी भी वीएफएल के संस्करण के साथ सीमा लागू होती है जो वर्तमान आईओएस 7.x के साथ जहाज है?
Drux

138

हां, इसके प्रारूप में दृश्य प्रारूप भाषा के साथ दृश्य को केंद्रित करना संभव है। दोनों लंबवत और क्षैतिज रूप से। यहाँ डेमो है:

https://github.com/evgenyneu/center-vfl


15
यह बहुत बढ़िया है, क्या आपको लगता है कि आप इस पर विस्तार कर सकते हैं और बता सकते हैं कि यह क्यों काम करता है?
तापी १

3
मैंने चिह्नित उत्तर के करीब कुछ का उपयोग करना समाप्त कर दिया है, लेकिन +1 आपके लिए एक गीथूब लगाव के लिए
रेम्ब्रांट Q. आइंस्टीन

4
@ यदि यह आपके लिए काम नहीं करता है, तो आपको चौड़ाई और ऊँचाई के साथ-साथ जगह की कमी भी हो सकती है। वीएफएल चौड़ाई के लिए इस तरह होगा: @ "[लेबल (== 200)]" और ऊंचाई के लिए इस तरह: @ "वी: [लेबल (== 200)]"
जोनाथन ज़ैन

1
से परिणाम क्यों हैं | और [पर्यवेक्षण] अलग? क्या यह कुछ ऐसा है जो रडार होना चाहिए या क्या वहां चल रहा है कि मैं बस का पालन नहीं कर रहा हूं?
मैट जी

3
बाधा प्रारूप को पार्स करने में असमर्थ: विकल्प मुखौटा को क्षैतिज किनारे पर संरेखित करने के लिए आवश्यक विचारों की आवश्यकता होती है, जो कि लेआउट के लिए भी अनुमति नहीं है जो क्षैतिज भी है। एच: [पर्यवेक्षी] - (<= 1) - [लेबल १]
हड़पने वाले

82

मुझे लगता है कि मैन्युअल रूप से अड़चनें पैदा करना बेहतर है।

[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 का उपयोग प्रोग्रामलैटली को स्वतः परिभाषित करने के लिए कर सकते हैं :

(IOS 9.0 और बाद में उपलब्ध)

view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true

मैं SnapKit का उपयोग करने की सलाह देता हूं , जो कि iOS और macOS दोनों पर ऑटो लेआउट को आसान बनाने के लिए एक DSL है।

view.snp.makeConstraints({ $0.center.equalToSuperview() })

1
सबसे अच्छा काम किया मेरे संदर्भ - हालांकि कोई VFL नहीं।
दिमागी तौर

यह मुझे एक चेतावनी देता है: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.
तापस पाल

10

पूरी तरह से यह इस तरह से करने में सक्षम था:

[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-(<=1)-[subview]"
                                        options:NSLayoutFormatAlignAllCenterY
                                        metrics:nil
                                          views:NSDictionaryOfVariableBindings(view, subview)];

यहाँ से यह सीखा स्पष्ट रूप से वाई द्वारा देखने पर केंद्र उपर्युक्त कोड।

Swift3:

        NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=1)-[subview]",
                                       options: .alignAllCenterY,
                                                       metrics: nil,
                                                       views: ["view":self, "subview":_spinnerView])

7

नीचे कोड जोड़ें और स्क्रीन के केंद्र में अपना बटन रखें। बिलकुल संभव है।

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

1

मुझे पता है कि यह आप नहीं चाहते हैं, लेकिन आप निश्चित रूप से मार्जिन की गणना कर सकते हैं और दृश्य प्रारूप स्ट्रिंग बनाने के लिए उनका उपयोग कर सकते हैं;)

वैसे भी, नहीं। दुर्भाग्य से वीएफएल के साथ 'स्वचालित रूप से' ऐसा करना संभव नहीं है - कम से कम अभी तक नहीं।


ठीक है, आप NSString stringWithFormat का उपयोग कर सकते हैं: अपने VFL स्ट्रिंग को गतिशील रूप से रनटाइम पर बनाने के लिए।
TRVD1707

1

@Evgenii के उत्तर के लिए धन्यवाद, मैं जिस्ट में एक पूर्ण उदाहरण बनाता हूं:

कस्टम ऊंचाई के साथ लंबवत रूप से लाल वर्ग को केंद्र में रखें

https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626

आप VFL (जो काफी सहज नहीं है) या मैन्युअल रूप से बाधाओं का उपयोग करके किसी दृश्य को केंद्र में रख सकते हैं। वैसे, मैं वीएफएल में केंद्र और ऊंचाई दोनों को एक साथ जोड़ नहीं सकता हूं:

"H:[subView]-(<=1)-[followIcon(==customHeight)]"

वर्तमान समाधान में VFL बाधाओं को अलग से जोड़ा जाता है।


0

यह क्या करना है कि पर्यवेक्षी को शब्दकोश में घोषित किया जाना चाहिए। उपयोग करने के बजाय |आप का उपयोग करें @{@"super": view.superview};

और NSLayoutFormatAlignAllCenterXऊर्ध्वाधर और NSLayoutFormatAlignAllCenterYविकल्पों के रूप में क्षैतिज के लिए।


0

आप अतिरिक्त दृश्यों का उपयोग कर सकते हैं।

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;

पुनश्च: मुझे यकीन नहीं है कि मैं अतिरिक्त विचारों को "प्लेसहोल्डर" कह सकता हूं, क्योंकि अंग्रेजी मेरी दूसरी भाषा है। यह सराहना की जाएगी अगर कोई मुझे बता सकता है कि।


यहाँ कुछ याद आ रहा है। आप विचारों की घोषणा के तहत ब्लॉक को कैसे कहते हैं ? यह एक कानूनी कोड नहीं है जिस तरह से आप इसे डालते हैं
इशाक

0

उन लोगों के लिए जो एक Interface Builderआधारित समाधान के लिए यहां आए थे (Google मुझे यहां ले जाता है), बस कांस्ट चौड़ाई / ऊंचाई की बाधाओं को जोड़ें, और सबव्यू का चयन करें -> इसे ड्रैग ड्रैग टू इट सुपरवाइवे -> सिलेक्ट "सेंटर वर्टिकली / हॉरिजॉन्टली इन सुपरवाइव"।


0

यह मेरी विधि है

//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])

-1

बस कहने की ज़रूरत है, कि आप इसका उपयोग बाधाओं के बजाय कर सकते हैं:

child.center = [parent convertPoint:parent.center fromView:parent.superview];

4
बस कहने की ज़रूरत है, कि वह क्या मांग रहा है और न ही यह काम करेगा यदि आप डिवाइस को घुमाते हैं, स्क्रीन को आकार दिया जाता है, आदि
jeffjv


-3

VFL का उपयोग करने के बजाय, आप इंटरफ़ेस बिल्डर में आसानी से कर सकते हैं। मुख्य स्टोरीबोर्ड में, ctrl + उस दृश्य पर क्लिक करें जिसे आप केंद्र में रखना चाहते हैं। पर्यवेक्षक पर खींचें (ctrl रखते हुए) और "सेंटर एक्स" या "सेंटर वाई" चुनें। कोई कोड की जरूरत है।

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