क्रमिक रूप से एक बहस बनाना


202

मेरे पास एक आम है UIViewControllerजो मेरे सभी UIViewsControllersकुछ सामान्य कार्यों का पुन: उपयोग करने के लिए विस्तारित होता है।

मैं इस "कॉमन" पर एक सेगमेंट स्थापित करना चाहता हूं UIViewControllerताकि अन्य सभी को UIViewControllersविरासत में मिले।

मैं यह पता लगाने की कोशिश कर रहा हूं कि मैं उस प्रोग्राम को कैसे कर सकता हूं।

मुझे लगता है कि सवाल यह भी हो सकता है कि मैं कहानी बोर्ड में जाने के बिना segueअपने सभी के लिए कैसे सेट करूं UIViewControllersऔर उन्हें हाथ से करूं।

जवाबों:


169

परिभाषा के अनुसार, एक सेगमेंट वास्तव में एक स्टोरीबोर्ड के स्वतंत्र रूप से मौजूद नहीं हो सकता है। यह वर्ग के नाम पर भी नहीं है: UIStoryboardSegue। आप क्रमिक रूप से सेगमेंट नहीं बनाते हैं - यह स्टोरीबोर्ड रनटाइम है जो आपके लिए उन्हें बनाता है। आप सामान्य रूप performSegueWithIdentifier:से अपने दृश्य नियंत्रक के कोड में कॉल कर सकते हैं , लेकिन यह स्टोरीबोर्ड में पहले से ही संदर्भ के लिए स्थापित एक सेगमेंट पर निर्भर करता है।

मुझे क्या लगता है कि आप पूछ रहे हैं कि कैसे आप अपने सामान्य दृश्य नियंत्रक (बेस क्लास) में एक विधि बना सकते हैं जो एक नए दृश्य नियंत्रक में संक्रमण करेगा, और सभी व्युत्पन्न वर्गों द्वारा विरासत में मिलेगा। आप इसे अपने बेस क्लास व्यू कंट्रोलर की तरह एक विधि बनाकर कर सकते हैं:

- (IBAction)pushMyNewViewController
{
    MyNewViewController *myNewVC = [[MyNewViewController alloc] init];

    // do any setup you need for myNewVC

    [self presentModalViewController:myNewVC animated:YES];
}

और फिर अपने व्युत्पन्न वर्ग में, उस विधि को कॉल करें जब उपयुक्त बटन पर क्लिक किया जाए या तालिका पंक्ति का चयन किया जाए या जो भी हो।


4
धन्यवाद। यह शर्म की बात है कि हम इसे प्रोग्रामेटिक रूप से नहीं कर सकते हैं। यह वास्तव में स्रोत कोड की गुणवत्ता को बढ़ावा देगा (कम दोहराव हमेशा अच्छा होता है)। मुझे आपके सुझाव के साथ जाना होगा।
टियागो वेलोसो

2
@ जोंक्रोल को स्विच स्टेटमेंट से कॉल करना / प्रदर्शन करना संभव है अर्थात मेरे पास कौन से इंडेक्स पर आधारित है?
कोडजुनकी

5
@codejunkie: हां, आप ऐसा कर सकते हैं। आप इसके लिए UIViewControllerनामित विधि का उपयोग करेंगे performSegueWithIdentifier:sender:
jonkroll

2
मैं क्रमिक रूप से प्रोग्राम बना रहा हूं और (मेरा जवाब देखें)। मेरे कोड में कुछ भी गलत है, तो, यदि आपका उत्तर सही है?
जीन-फिलिप पेलेट

13
IOS 6+ के लिए अद्यतन: UIViewके presentModalViewController:animated:मान्य नहीं है। से डॉक्स - (आईओएस 6.0 में पदावनत उपयोग presentViewController: एनिमेटेड: पूरा होने:।। बजाय)
उपयोगकर्ता

346

मैंने सोचा कि मैं एक और संभावना जोड़ूंगा। आपके द्वारा की जाने वाली चीजों में से एक है कि आप एक स्टोरीबोर्ड में दो दृश्यों को एक सेग का उपयोग करके कनेक्ट कर सकते हैं जो एक एक्शन से जुड़ा नहीं है, और फिर प्रोग्रामेटिक रूप से अपने व्यू कंट्रोलर के अंदर सेग को ट्रिगर करें। जिस तरह से आप ऐसा करते हैं, वह यह है कि आपको स्टोरीबोर्ड दृश्य के तल पर फ़ाइल के स्वामी आइकन से खींचना होगा जो कि सीज़िंग दृश्य है, और गंतव्य दृश्य के लिए सही खींचें। मैं एक छवि में मदद करने के लिए फेंक दूँगा।

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

एक पॉपअप "मैनुअल लीग" के लिए दिखाई देगा। मैंने पुश को टाइप के रूप में उठाया। थोड़ा वर्ग पर टैप करें और सुनिश्चित करें कि आप गुण निरीक्षक में हैं। इसे एक पहचानकर्ता दें जिसे आप इसे कोड में संदर्भित करने के लिए उपयोग करेंगे।

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

ठीक है, आगे मैं एक प्रोग्राम बार बटन आइटम का उपयोग करके बहस करने जा रहा हूं। ViewDidLoad या कहीं और मैं इस कोड के साथ नेविगेशन बार पर एक बटन आइटम बनाऊंगा:

UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:@"Buttonize"
                                                                    style:UIBarButtonItemStyleDone
                                                                   target:self
                                                                   action:@selector(buttonizeButtonTap:)];
self.navigationItem.rightBarButtonItems = @[buttonizeButton];

ठीक है, ध्यान दें कि चयनकर्ता बटनपट्टी बटन है:। तो उस बटन के लिए एक शून्य विधि लिखें और उस पद्धति के भीतर आप इस तरह से बहस करेंगे:

-(void)buttonizeButtonTap:(id)sender{
    [self performSegueWithIdentifier:@"Associate" sender:sender];
    }

तैयार करने के लिए प्रेषक पैरामीटर को बटन की पहचान करने की आवश्यकता होती है। readyForSegue फ्रेमवर्क विधि है जहां आप अपने दृश्य को तुरंत बदल देंगे और इसे अपने काम को करने के लिए जो भी मूल्यों की आवश्यकता होगी उसे पारित करेंगे। यहाँ मेरा तरीका कैसा दिखता है:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"Associate"])
    {
        TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController];
        translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController
        translationQuizAssociateVC.contentID = self.contentID;
        translationQuizAssociateVC.index = self.index;
        translationQuizAssociateVC.content = self.content;
    }
}

ठीक है, बस इसका परीक्षण किया और यह काम करता है। आशा है कि यह आपकी मदद करता है।


@MichaelRowe यह सेगमेंट की आवश्यकता को कैसे समाप्त करता है? जैसा कि मैंने देखा है कि आपको अभी भी स्टोरीबोर्ड पर डेस्टिनेशन कंट्रोलर पर ड्रैग और ड्रॉप करना है ..
एरिक्रिक

@MichaelRowe यह सेगमेंट की आवश्यकता को समाप्त नहीं करता है। यह क्या करता है आपको इंटरफ़ेस कंट्रोलर के बजाय कोड में बनाए गए दृश्य नियंत्रकों के बीच बहस करने देता है।
मैथ्यू

@ यह वास्तव में सिर्फ मुझे पूरी तरह से पुनर्विचार करने के लिए जाता है कि मैं अपने ऐप को कैसे सेटअप करता हूं ... सभी यूआई के पूर्ण पुनर्लेखन के बाद मैं अब किसी भी सेगमेंट का उपयोग नहीं करता हूं ..
माइकल रोवे

@ कोकोनट मैं त्रुटि प्राप्त कर रहा हूं क्योंकि "आवेदन ने एक सक्रिय नियंत्रक को पेश करने की कोशिश की" इस बारे में कोई मदद ..
बाला

1
मैनुअल सेगमेंट "पुश" पदावनत है, "शो" का उपयोग करें। इस उत्तर में अधिक विवरण हैं। @smileBot कृपया जवाब अपडेट करें।
नायबास

81

मैं इस कोड का उपयोग अपने कस्टम सेग उपक्लास को तुरंत करने और प्रोग्रामेटिक रूप से चलाने के लिए कर रहा हूँ। यह काम करने लगता है। इसमें कुछ भी गलत है? मैं हैरान हूँ, यह कहते हुए कि यह नहीं किया जा सकता अन्य सभी उत्तरों को पढ़कर।

UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"OtherViewControllerId"];
MyCustomSegue *segue = [[MyCustomSegue alloc] initWithIdentifier:@"" source:self destination:toViewController];
[self prepareForSegue:segue sender:sender];
[segue perform];

4
MyCustomSegue में क्या है?
विक्टर एंगेल

3
यह एक कस्टम उपवर्ग है UIStoryboardSegue
जीन-फिलिप पेलेट

7
@MarkAmery बहुत से लोग (मेरे सहित) स्टोरीबोर्ड का उपयोग करने से बचते हैं। वे मर्ज करना मुश्किल है, और कोई संकलन-समय की जाँच नहीं है कि मैं जिस आईडी से गुजर रहा हूँ performSegueWithIdentifier:वह वास्तव में स्टोरीबोर्ड में परिभाषित है। मैं सभी समस्याओं से बचता हूं यदि मैं स्वयं सेगमेंट बनाता हूं।
जीन-फिलिप पेलेट

3
मैं जीन-फिलिप से सहमत हूं। स्टोरीबोर्ड को प्रबंधित करना बट में दर्द है। बेशक, कुछ विचारों को क्रेट करना और यहां एक सेगमेंट को जोड़ना और वहाँ एक सेग के माध्यम से अपना रास्ता क्लिक करना आसान है, लेकिन XML में परिभाषित 16 सेगमेंट के साथ 6 विचारों का प्रबंधन करना, जब आपके पास तीन डेवलपर्स हैं, तो इसके साथ सभी पहेलियां भयानक हैं। वैसे भी, मुद्दा यह है: कोड आपको नियंत्रण देता है, xcode द्वारा उत्पन्न xml नहीं करता है।
क्रिस्टियन

3
मुझे iOS7 में [segue perform] में एक क्रैश दिखाई देता है, यकीन नहीं होता कि किसी और को यह अनुभव हो रहा है।
एरिक चेन

45

यह माना जाता है कि इसका उत्तर दिया गया है और स्वीकार किया गया है, लेकिन मैं इसके साथ कुछ और विवरण जोड़ना चाहूंगा।

मैंने एक समस्या को हल करने के लिए क्या किया, जहां मैं पहली स्क्रीन के रूप में एक लॉगिन-दृश्य प्रस्तुत करूंगा और फिर लॉगिन सही होने पर आवेदन पर बहस करना चाहता था। मैंने लॉगिन-व्यू कंट्रोलर से रूट व्यू कंट्रोलर तक सेगमेंट बनाया और इसे "myidentifier" की तरह एक पहचानकर्ता दिया।

फिर सभी लॉगिन कोड की जांच करने के बाद अगर लॉगिन सही था तो मैं कॉल करूंगा

[self performSegueWithIdentifier: @"myidentifier" sender: self];

मेरी सबसे बड़ी गलतफहमी यह थी कि मैंने एक बार मिल जाने पर सेग को एक बटन पर रखने की कोशिश की और एक बार इस तरह की रुकावट आई।


4
जैसा कि मैंने एक और टिप्पणी के रूप में लिखा है: मैं कस्टम सेगमेंट को प्रोग्रामेटिक रूप से बना रहा हूं और प्रदर्शन कर रहा हूं (मेरा उत्तर देखें)।
जीन-फिलिप पेलेट

32

आपको अपने कोड को उस लिंक से जोड़ना होगा UIStoryboardजिसका आप उपयोग कर रहे हैं। सुनिश्चित करें कि आप अपने में YourViewController में जाते हैं UIStoryboard, इसके चारों ओर की सीमा पर क्लिक करें और फिर अपने identifierफ़ील्ड को NSStringअपने कोड में कॉल करने वाले पर सेट करें।

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" 
                                                     bundle:nil];
YourViewController *yourViewController = 
 (YourViewController *)
  [storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerID"];
[self.navigationController pushViewController:yourViewController animated:YES];

1
मुझे यह मिल जाता है, लेकिन क्या होगा यदि मैं जिस व्यू-कंट्रौलर को प्रस्तुत करना चाहता हूं, वह स्टोरीबोर्ड में एक नेविगेशनकंट्रोलर में एम्बेडेड है? जो मुझे मिल सकता है, उससे मैं इसे एम्बेड करने के लिए एक नेविगेशनकंट्रोलर को इनिशियलाइज़ कर सकता हूं, लेकिन स्टोरीबोर्ड में, मेरे पास पहले से ही उस दृश्य के लिए पुश सीगेज़ सेटअप है जिसे प्रस्तुत करने की आवश्यकता है।
jhilgert00

1
क्या आप इसे विस्तार से बताएंगे? मुझे लगता है कि यह समस्या है जो मुझे हो रही है, लेकिन यह पता नहीं लग सकता है कि यह कैसे / कहाँ करना है ...
jesses.co.tt

1
यहां तक ​​कि यह समाधान एक सही है, यह किसी भी बहस से बचने के बारे में है, लेकिन सवाल सेज के बारे में है। इस तरह आप स्टोरीबोर्ड में सेगमेंट के बिना दो दृश्य के बीच एक संक्रमण को जोड़ सकते हैं या बना सकते हैं।
बूटमेकर

16

कंट्रोलर के लिए जो स्टोरीबोर्ड में हैं।

jhilgert00 यह आप क्या देख रहे थे?

-(IBAction)nav_goHome:(id)sender {
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:@"HomeController"];
[self.navigationController pushViewController: myController animated:YES];

}

या ...

[self performSegueWithIdentifier:@"loginMainSegue" sender:self];

3

ठीक है, आप बना सकते हैं और UIStoryBoardSegue को भी उपवर्गित कर सकते हैं। सबक्लासिंग का उपयोग ज्यादातर कस्टम ट्रांज़िशन एनीमेशन देने के लिए किया जाता है।

आप wwdc 2011 का वीडियो देख सकते हैं जिसमें StoryBoard शुरू किया गया है। youtube में भी उपलब्ध है।

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIStoryboardSegue_Class/Reference/Reference.html#//apple_ref/occ/cl/UIStoryboardSegue


3

मैं एक स्पष्टीकरण जोड़ना चाहूंगा ...

एक आम गलतफहमी, वास्तव में जो मुझे कुछ समय के लिए थी, वह यह है कि एक स्टोरीबोर्ड सेग को prepareForSegue:sender:विधि द्वारा ट्रिगर किया जाता है। यह नहीं। एक स्टोरीबोर्ड सेगमेंट प्रदर्शन करेगा, भले ही आपने उस के लिए एक prepareForSegue:sender:विधि लागू की हो (से प्रस्थान) दृश्य नियंत्रक।

मैंने पॉल हेगार्टी के उत्कृष्ट आईट्यून्स व्याख्यान से यह सीखा । मेरी माफी लेकिन दुर्भाग्य से कौन सा व्याख्यान याद नहीं कर सकता।

यदि आप एक स्टोरीबोर्ड में दो दृश्य नियंत्रकों के बीच एक सेगमेंट कनेक्ट करते हैं, लेकिन एक prepareForSegue:sender:विधि को लागू नहीं करते हैं , तो segue अभी भी लक्ष्य दृश्य नियंत्रक से बहस करेगा। हालाँकि यह उस व्यू कंट्रोलर से अप्रकाशित होगा।

उम्मीद है की यह मदद करेगा।


3

स्टोरीबोर्ड के बाहर स्टोरीबोर्ड सेगमेंट नहीं बनाए जाने हैं। कमियां होने के बावजूद आपको इसे वायर करने की आवश्यकता होगी।

UIStoryboardSegue संदर्भ स्पष्ट रूप से बताता है:

आप सीधे सेगमेंट ऑब्जेक्ट नहीं बनाते हैं। इसके बजाय, स्टोरीबोर्ड रनटाइम उन्हें बनाता है जब इसे दो दृश्य नियंत्रकों के बीच एक सेगमेंट करना होगा। यदि आप चाहते हैं, तो आप अभी भी एक प्रोग्राम को निष्पादित कर सकते हैं। आप ऐसा स्रोत से एक प्रोग्राम शुरू करने के लिए कर सकते हैं जो प्रोग्रामेटिक रूप से जोड़ा गया था और इसलिए इंटरफ़ेस बिल्डर में उपलब्ध नहीं है।

आप अभी भी प्रोग्रामबोर्ड को कह सकते हैं कि एक दृश्य नियंत्रक को कॉल presentModalViewController:या pushViewController:animated:कॉल का उपयोग करके दृश्य नियंत्रक प्रस्तुत करना है, लेकिन आपको स्टोरीबोर्ड उदाहरण की आवश्यकता होगी।

UIStoryboardमुख्य बंडल के लिए बंडल nil के साथ एक नामित स्टोरीबोर्ड प्राप्त करने के लिए आप s क्लास विधि कह सकते हैं ।

storyboardWithName:bundle:


2

सबसे पहले, मान लीजिए कि आपके पास स्टोरीबोर्ड में दो अलग-अलग विचार हैं, और आप एक स्क्रीन से दूसरे स्क्रीन पर नेविगेट करना चाहते हैं, इसलिए इस चरणों का पालन करें:

1)। कक्षा फ़ाइल और पहचान निरीक्षक में स्टोरीबोर्ड आईडी के साथ अपने सभी विचारों को परिभाषित करें।

2)। सुनिश्चित करें कि आप पहले दृश्य में एक नेविगेशन नियंत्रक जोड़ते हैं। इसे स्टोरीबोर्ड में चुनें और फिर संपादक> एंबेड इन> नेविगेशन नियंत्रक

3)। अपनी पहली कक्षा में, "secondClass.h" आयात करें

#import "ViewController.h
#import "secondController.h"

4)। इस कमांड को IBAction में जोड़ें जिसे segue करना है

secondController *next=[self.storyboard instantiateViewControllerWithIdentifier:@"second"];
[self.navigationController pushViewController:next animated:YES];

5)। @"second"सेकंडव्यू कंट्रोलर क्लास, स्टोरीबोर्ड आईडी है।


self.storyboardहोना चाहिए:UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
masipcat

@masipcat और स्टोरी बोर्ड का नाम इस बात पर निर्भर हो सकता है कि आपने अपना Xcode प्रोजेक्ट कैसे सेट किया है, मेरा यह "Main.storyboard" था इसलिए मैंने इस्तेमाल कियाstoryboardWithName:@"Main"
ammianus

@ sanket-chauhan अगर आपका पहला कंट्रोलर किसी नैविगेशन कंट्रोलर में [self showDetailViewController:next sender:self];[self showViewController:next sender:self];
इंबेडेड

1

मैंने रिवर्स-इंजीनियर किया और UIStoryboard के सेगमेंट का एक खुला स्रोत (पुनः) कार्यान्वयन: https://github.com/acoomans/Segway

उस लाइब्रेरी के साथ, आप प्रोग्राम को बिना किसी स्टोरीबोर्ड (बिना किसी स्टोरीबोर्ड) के परिभाषित कर सकते हैं।

आशा है कि यह मदद कर सकता है।


0

समस्याओं की एक जोड़ी, वास्तव में:

सबसे पहले, उस परियोजना में जो आपने हमारे लिए अपलोड की है, सेगमेंट "segue1" पहचानकर्ता को सहन नहीं करता है:

कोई पहचानकर्ता नहीं

यदि आप पहले से ही नहीं है तो आपको उस पहचान पत्र को भरना चाहिए।

दूसरा, जैसा कि आप टेबल व्यू से टेबल व्यू पर जोर दे रहे हैं, आप व्यू कंट्रोलर बनाने के लिए initWithNibName कह रहे हैं। आप वास्तव में InstantiateViewControllerWithIdentifier का उपयोग करना चाहते हैं।


0

यहाँ के लिए कोड नमूना है Creating a segue programmatically:

class ViewController: UIViewController {
    ...
    // 1. Define the Segue
    private var commonSegue: UIStoryboardSegue!
    ...
    override func viewDidLoad() {
        ...
        // 2. Initialize the Segue
        self.commonSegue = UIStoryboardSegue(identifier: "CommonSegue", source: ..., destination: ...) {
            self.commonSegue.source.showDetailViewController(self.commonSegue.destination, sender: self)
        }
        ...
    }
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // 4. Prepare to perform the Segue
        if self.commonSegue == segue {
            ...
        }
        ...
    }
    ...
    func actionFunction() {
        // 3. Perform the Segue
        self.prepare(for: self.commonSegue, sender: self)
        self.commonSegue.perform()
    }
    ...
}

आप self.prepare(for: self.commonSegue, sender: self)अपने एक्शन विधि से बुला रहे हैं । तब की तुलना की बात क्या है if self.commonSegue == segue {...}में prepare(for:sender)विधि?
नईम

@nayem: इसमें prepare(for:sender:), आप गंतव्य दृश्य नियंत्रक को प्रदर्शित होने से पहले कॉन्फ़िगर कर सकते हैं। बेशक आप भी इसमें कर सकते हैं actionFunction
jqgsninimo

@nayem: ऐसा करने का कारण यह है कि मैं अन्य सेगमेंट की हैंडलिंग के अनुरूप होने की कोशिश कर रहा हूं।
jqgsninimo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.