আপনি কীভাবে সুইফটে ভিউ কন্ট্রোলার এবং অন্যান্য অবজেক্টের মধ্যে ডেটা ভাগ করবেন?


88

বলুন আমার সুইফট অ্যাপে আমার একাধিক ভিউ কন্ট্রোলার রয়েছে এবং আমি তাদের মধ্যে ডেটা পাস করতে সক্ষম হতে চাই। যদি আমি একটি ভিউ কন্ট্রোলার স্ট্যাকের কয়েক স্তরে নীচে থাকি, তবে আমি কীভাবে অন্য ভিউ কন্ট্রোলারের কাছে ডেটা পাস করব? বা একটি ট্যাব বারের মধ্যে ট্যাবগুলির মধ্যে ভিউ নিয়ন্ত্রণকারী?

(দ্রষ্টব্য, এই প্রশ্নটি একটি "রিঞ্জার")) এটি এত বেশি জিজ্ঞাসিত হয় যে আমি এই বিষয়ে টিউটোরিয়াল লেখার সিদ্ধান্ত নিয়েছি। আমার উত্তর নীচে দেখুন।


4
প্রতিনিধিদের জন্য
গুগল করার

4
আমি এটি পোস্ট করেছি যাতে আমি এখানে এই প্রশ্নের 10,000 টি উদাহরণের সমাধান দিতে পারি যা এখানে এসও-তে প্রতিদিন প্রদর্শিত হয়। আমার স্ব-উত্তর দেখুন। :)
ডানকান সি

দুঃখিত আমি প্রতিক্রিয়া জানাতে খুব দ্রুত ছিলাম :) এর সাথে লিঙ্ক করতে সক্ষম
হলাম

4
কোন চিন্তা করো না. আপনি ভেবেছিলেন আমি # 10,001, তাই না? <grin>
ডানকান সি

4
পছন্দ করুন :( এটি প্রতিটি দৃশ্যের জবাব হিসাবে ধরা ঠিকই নয় ... অনির্দিষ্ট, এটি প্রতিটি দৃশ্যের জন্য কাজ করবে , তবে এটি প্রায় কোনও দৃশ্যের জন্যও সঠিক পদ্ধতি নয় । সত্ত্বেও, আমরা এখন এটি আমাদের মাথায় নিয়ে এসেছি've এই যেহেতু এই প্রশ্নের সদৃশ হিসাবে কোনও প্রশ্ন চিহ্নিত করা ভাল ধারণা? দয়া করে, করবেন না
nhgrif

উত্তর:


91

আপনার প্রশ্নটি খুব বিস্তৃত। প্রতিটি দৃশ্যের একটি সহজ ক্যাচ-সমস্ত সমাধান রয়েছে তা বোঝানোর জন্য হ'ল কিছুটা নির্বোধ। সুতরাং, আসুন এর কিছু দৃশ্যের মধ্য দিয়ে যাওয়া যাক।


আমার অভিজ্ঞতায় স্ট্যাক ওভারফ্লো সম্পর্কে সর্বাধিক সাধারণ পরিস্থিতি সম্পর্কে জিজ্ঞাসা করা হ'ল এক ভিউ কন্ট্রোলার থেকে পরের দিকে সরল তথ্য information

যদি আমরা স্টোরিবোর্ড ব্যবহার করি তবে আমাদের প্রথম দেখা নিয়ন্ত্রক ওভাররাইড করতে পারে prepareForSegue, এটি ঠিক সেখানেই রয়েছে। UIStoryboardSegueযখন এই পদ্ধতিটি বলা হয় তখন কোনও বস্তু পাস করা হয় এবং এতে আমাদের গন্তব্য দেখার নিয়ন্ত্রকের একটি উল্লেখ থাকে। এখানে, আমরা যে মানগুলি পাস করতে চাই তা সেট করতে পারি।

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "MySegueID" {
        if let destination = segue.destination as? SecondController {
            destination.myInformation = self.myInformation
        }
    }
}

বিকল্পভাবে, যদি আমরা স্টোরিবোর্ডগুলি ব্যবহার না করি, তবে আমরা একটি নিব থেকে আমাদের ভিউ কন্ট্রোলারটি লোড করছি। আমাদের কোডটি তখন কিছুটা সহজ।

func showNextController() {
    let destination = SecondController(nibName: "SecondController", bundle: nil)
    destination.myInformation = self.myInformation
    show(destination, sender: self)
}

উভয় ক্ষেত্রেই, myInformationপ্রতিটি ভিউ কন্ট্রোলারের একটি সম্পত্তি হ'ল এক ভিউ নিয়ন্ত্রক থেকে পরবর্তী ভিউতে যা যা করা দরকার তা হোল্ড করে। প্রতিটি কন্ট্রোলারে অবশ্যই তাদের একই নাম থাকতে হবে না।


আমরা একটি এ ট্যাবগুলির মধ্যেও তথ্য ভাগ করতে চাই UITabBarController

এই ক্ষেত্রে, এটি সম্ভবত সম্ভাব্য এমনকি সহজ।

প্রথমে আসুন এর একটি সাবক্লাস তৈরি করি UITabBarController, এবং বিভিন্ন ট্যাবগুলির মধ্যে আমরা যে তথ্য ভাগ করতে চাই তার জন্য এটির বৈশিষ্ট্য দাও:

class MyCustomTabController: UITabBarController {
    var myInformation: [String: AnyObject]?
}

এখন আমরা স্টোরিবোর্ড থেকে আমাদের অ্যাপ্লিকেশন তৈরি করছি, তাহলে আমরা কেবল আমাদের ট্যাব বার নিয়ামক এর বর্গ ডিফল্ট থেকে পরিবর্তন UITabBarControllerকরতে MyCustomTabController। যদি আমরা স্টোরিবোর্ডটি ব্যবহার না করে থাকি তবে আমরা কেবলমাত্র ডিফল্ট UITabBarControllerক্লাসের চেয়ে এই কাস্টম শ্রেণীর একটি উদাহরণ ইনস্ট্যান্ট করি এবং এতে আমাদের ভিউ কন্ট্রোলার যুক্ত করি।

এখন, ট্যাব বার নিয়ামকের মধ্যে থাকা আমাদের সমস্ত দর্শনীয় কন্ট্রোলার এই সম্পত্তিটি অ্যাক্সেস করতে পারে:

if let tbc = self.tabBarController as? MyCustomTabController {
    // do something with tbc.myInformation
}

এবং UINavigationControllerএকইভাবে সাবক্লাসিংয়ের মাধ্যমে, আমরা পুরো নেভিগেশন স্ট্যাকের মধ্যে ডেটা ভাগ করে নেওয়ার জন্য একই পন্থা নিতে পারি:

if let nc = self.navigationController as? MyCustomNavController {
    // do something with nc.myInformation
}

আরও বেশ কয়েকটি পরিস্থিতি রয়েছে। কোনওভাবেই এই উত্তরটি তাদের সমস্তকে কভার করে না।


4
আমি আরও যোগ করব যে কখনও কখনও আপনি চ্যানেলটি গন্তব্য দৃশ্যের নিয়ন্ত্রক থেকে উত্স ভিউ নিয়ন্ত্রকের কাছে তথ্য ফেরত পাঠাতে চান। এই পরিস্থিতিটি হ্যান্ডেল করার একটি সাধারণ উপায় হ'ল গন্তব্যে কোনও প্রতিনিধি সম্পত্তি যুক্ত করা এবং তারপরে সোর্স ভিউ কন্ট্রোলারের রেফারেন্সফেরসিতে, গন্তব্য দর্শন নিয়ন্ত্রকের প্রতিনিধি সম্পত্তিটিকে নিজেরাই সেট করুন। (এবং এমন একটি প্রোটোকল সংজ্ঞায়িত করুন যা গন্তব্য ভিসি উত্স ভিসিতে বার্তা প্রেরণের জন্য ব্যবহার করে এমন বার্তাগুলিকে সংজ্ঞায়িত করে)
ডানকান সি

4
nhgrif, আমি সম্মত নতুন বিকাশকারীদের পরামর্শটি হ'ল যদি আপনার স্টোরিবোর্ডের দৃশ্যের মধ্যে ডেটা পাস করার প্রয়োজন হয় তবে ব্যবহার করুন prepareForSegue। এটি খুব খারাপ যে এখানে খুব উত্তর দেওয়া যায় না এবং উত্তরগুলি এবং উত্তরগুলির মধ্যে এই খুব সাধারণ পর্যবেক্ষণটি হারিয়ে যায়।
রব

4
@ রব ইয়ুপ সিলেটলেট এবং বিজ্ঞপ্তিগুলি সর্বশেষ পছন্দ হওয়া উচিত। আমাদের প্রায় প্রতিটি দৃশ্যে তথ্য prepareForSegueবা অন্যান্য প্রত্যক্ষ স্থানান্তরকে অগ্রাধিকার দেওয়া উচিত এবং তারপরে নবাগতরা যখন তাদের পরিস্থিতিটি কার্যকর হয় না এমন দৃশ্যের সাথে প্রদর্শিত হয় এবং তখন আমাদের আরও বিশ্বব্যাপী পদ্ধতি সম্পর্কে তাদের শিখিয়ে দিতে হবে।
nhgrif

4
এটা নির্ভর করে. তবে আমি খুব, খুব বেশি উদ্বিগ্ন হয়েছি অ্যাপটির প্রতিনিধিটিকে কোডের জন্য আমাদের ডাম্পিং গ্রাউন্ড হিসাবে ব্যবহার করার বিষয়ে আমরা জানি না যে আর কোথায় রাখব। এখানে পাগলের পথ রয়েছে।
nhgrif

4
@ হ্নগ্রিফ আপনার উত্তরের জন্য ধন্যবাদ। তবে যদি আপনি চান 4 বা 5 ভিউকন্ট্রোলারদের মধ্যে ডেটাটি পাস করতে চান। যদি আইভি 4-5 ভিউকন্ট্রোলারগণ ক্লায়েন্ট লগইন এবং পাসওয়ার্ড পরিচালনা করতে পারে এবং আমি এই ভিউকন্ট্রোলারদের মধ্যে ব্যবহারকারীর ইমেলটি পাস করতে চাই, তবে প্রতিটি ভিউকন্ট্রোলারে ভ্যারিয়াল ঘোষণার পরে এটি প্রস্তুত করার চেয়ে আরও সহজ উপায় কি? আমি কীভাবে একবার ঘোষনা করতে পারি এবং প্রতিটি দর্শনার্থী এটি অ্যাক্সেস করতে পারে এমন উপায় কি তবে এটিও ভাল কোডিং অনুশীলন?
লজফ্লান

45

এই প্রশ্নটি সব সময় উঠে আসে।

একটি পরামর্শ হ'ল ডেটা কনটেইনার সিঙ্গলটন তৈরি করা: এমন একটি বস্তু যা আপনার অ্যাপ্লিকেশনটির জীবনে একবারে এবং একবারে তৈরি হয়ে যায় এবং আপনার অ্যাপ্লিকেশনটির জন্য স্থায়ী হয়।

যখন আপনার কাছে বিশ্বব্যাপী অ্যাপ্লিকেশন ডেটা রয়েছে তখন আপনার অ্যাপ্লিকেশনটিতে বিভিন্ন শ্রেণীর জন্য উপলব্ধ / সংশোধনযোগ্য হতে হবে তখন এই পদ্ধতির জন্য উপযুক্ত।

ভিউ কন্ট্রোলারগুলির মধ্যে ওয়ান-ওয়ে বা দ্বি-মুখী লিঙ্ক স্থাপনের মতো অন্যান্য পন্থাগুলি আপনি যেখানে পরিস্থিতি নিয়ন্ত্রণকারীদের মধ্যে সরাসরি তথ্য / বার্তা প্রেরণ করছেন সেই পরিস্থিতিতে উপযুক্ত better

(অন্যান্য বিকল্পের জন্য নীচে এনএইচগ্রিফের উত্তর দেখুন))

ডেটা কন্টেইনার সিঙ্গলটনের সাহায্যে আপনি আপনার শ্রেণিতে এমন একটি সম্পত্তি যুক্ত করুন যা আপনার সিঙ্গলটনের একটি রেফারেন্স সঞ্চয় করে এবং তারপরে আপনার যে কোনও সময় অ্যাক্সেসের প্রয়োজন হলে সেই সম্পত্তিটি ব্যবহার করুন।

আপনি আপনার সিঙ্গেলটন সেট আপ করতে পারেন যাতে এটির বিষয়বস্তুগুলি ডিস্কে সংরক্ষণ করে যাতে আপনার অ্যাপের অবস্থা লঞ্চগুলির মধ্যে স্থির থাকে।

আপনি কীভাবে এটি করতে পারেন তা প্রদর্শন করে আমি গিটহাবে একটি ডেমো প্রকল্প তৈরি করেছি। লিঙ্কটি এখানে:

গিটহাবের সুইফটডাটা কন্টেইনারসিংটন প্রকল্পটি এখানে সেই প্রকল্পটি থেকে পুনরায় পড়ুন:

সুইফটডাটা কন্টেইনারসিংলেটন

অ্যাপ্লিকেশন স্থিতি সংরক্ষণ করতে এবং বস্তুর মধ্যে ভাগ করে নেওয়ার জন্য ডেটা কন্টেইনার সিঙ্গলটন ব্যবহারের একটি প্রদর্শন ration

DataContainerSingletonবর্গ প্রকৃত Singleton হয়।

এটি sharedDataContainerসিঙ্গলটনের একটি রেফারেন্স সংরক্ষণ করতে একটি স্ট্যাটিক ধ্রুবক ব্যবহার করে।

সিঙ্গলটনে অ্যাক্সেস করতে সিনট্যাক্সটি ব্যবহার করুন

DataContainerSingleton.sharedDataContainer

নমুনা প্রকল্পটি ডেটা ধারকটিতে 3 টি বৈশিষ্ট্য নির্ধারণ করে:

  var someString: String?
  var someOtherString: String?
  var someInt: Int?

someIntডেটা ধারক থেকে সম্পত্তি লোড করতে , আপনি এই জাতীয় কোড ব্যবহার করুন:

let theInt = DataContainerSingleton.sharedDataContainer.someInt

কিছুতে কোনও মান সংরক্ষণ করতে, আপনি সিনট্যাক্সটি ব্যবহার করবেন:

DataContainerSingleton.sharedDataContainer.someInt = 3

ডেটা কন্টেইনারসিংলেটনের initপদ্ধতিটি এর জন্য একটি পর্যবেক্ষক যুক্ত করে UIApplicationDidEnterBackgroundNotification। কোডটি এর মতো দেখাচ্ছে:

goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
  UIApplicationDidEnterBackgroundNotification,
  object: nil,
  queue: nil)
  {
    (note: NSNotification!) -> Void in
    let defaults = NSUserDefaults.standardUserDefaults()
    //-----------------------------------------------------------------------------
    //This code saves the singleton's properties to NSUserDefaults.
    //edit this code to save your custom properties
    defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
    defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
    defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
    //-----------------------------------------------------------------------------

    //Tell NSUserDefaults to save to disk now.
    defaults.synchronize()
}

পর্যবেক্ষক কোডে এটি ডেটা ধারকটির বৈশিষ্ট্যগুলিতে সংরক্ষণ করে NSUserDefaults। আপনি NSCodingস্টেটের ডেটা সংরক্ষণের জন্য কোর ডেটা বা অন্যান্য বিভিন্ন পদ্ধতিও ব্যবহার করতে পারেন ।

ডেটা কন্টেইনারসিংটনের initপদ্ধতিটিও এর বৈশিষ্ট্যগুলির জন্য সংরক্ষিত মান লোড করার চেষ্টা করে।

আর ডি পদ্ধতির সেই অংশটি দেখতে এরকম দেখাচ্ছে:

let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------

এনএসইউসারডেফল্টগুলিতে মান লোড এবং সংরক্ষণের কীগুলি স্ট্রিং ধ্রুবক হিসাবে সংরক্ষণ করা হয় যা স্ট্রাক্টের অংশ, এটি এর DefaultsKeysমতো সংজ্ঞায়িত হয়:

struct DefaultsKeys
{
  static let someString  = "someString"
  static let someOtherString  = "someOtherString"
  static let someInt  = "someInt"
}

আপনি এই ধ্রুবকগুলির মধ্যে একটির মতো উল্লেখ করুন:

DefaultsKeys.someInt

ডেটা কনটেইনার সিঙ্গলটন ব্যবহার করে:

এই নমুনা অ্যাপ্লিকেশনটি ডেটা কন্টেইনার সিঙ্গলটনের ত্রিভুজ ব্যবহার করে।

দু'জন ভিউ কন্ট্রোলার রয়েছে। প্রথমটি ইউআইভিউকন্ট্রোলারের একটি কাস্টম সাবক্লাস ViewControllerএবং দ্বিতীয়টি ইউআইভিউকন্ট্রোলারের একটি কাস্টম সাবক্লাস SecondVC

উভয় দর্শনীয় কন্ট্রোলারের একটি পাঠ্য ক্ষেত্র থাকে এবং উভয়ই someIntতাদের viewWillAppearপদ্ধতিতে তথ্য ধারক সিঙ্গলল্টনের সম্পত্তি থেকে পাঠ্য ক্ষেত্রের মধ্যে একটি মান লোড করে এবং উভয়ই পাঠ্য ক্ষেত্র থেকে বর্তমান মানটিকে ডেটা ধারকটির 'কিছুটা' সংরক্ষণ করে।

পাঠ্য ক্ষেত্রে মানটি লোড করার কোডটি viewWillAppear:পদ্ধতিতে রয়েছে:

override func viewWillAppear(animated: Bool)
{
  //Load the value "someInt" from our shared ata container singleton
  let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
  
  //Install the value into the text field.
  textField.text =  "\(value)"
}

ব্যবহারকারী-সম্পাদিত মানটিকে ডেটা ধারকটিতে ফিরিয়ে আনার কোডটি দেখুন নিয়ন্ত্রকের textFieldShouldEndEditingপদ্ধতিতে রয়েছে:

 func textFieldShouldEndEditing(textField: UITextField) -> Bool
 {
   //Save the changed value back to our data container singleton
   DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
   return true
 }

আপনার ভিউউইল অ্যাপ্লায়ারটি ভিউডিল অ্যাপের পরিবর্তে আপনার ইউজার ইন্টারফেসে মানগুলি লোড করা উচিত যাতে প্রতিবারের নিয়ামক প্রদর্শনের সময় আপনার ইউআই আপডেট হয়।


8
আমি এটিকে নিচে ভোট দিতে চাই না কারণ আমি মনে করি এটি উত্সাহ যে উত্সাহ হিসাবে আপনি প্রশ্ন তৈরি করার জন্য সময় ব্যয় করেছিলেন এবং উত্স হিসাবে উত্তর দিয়েছেন। ধন্যবাদ. তা সত্ত্বেও, আমি মনে করি আমরা নতুন বিকাশকারীদের কাছে মডেল অবজেক্টগুলির জন্য সিঙ্গলেটনের পক্ষে পরামর্শ দেওয়ার জন্য একটি দুর্দান্ত প্রতিরোধ করি। আমি "সিঙ্গলেটস অশুভ" শিবিরে নেই (যদিও বিষয়গুলির আরও ভালভাবে প্রশংসা করার জন্য নুবগুলি এই শব্দগুচ্ছটি গুগল করা উচিত) তবে আমি মনে করি মডেল ডেটা সিঙ্গলেটনের প্রশ্নবিদ্ধ / বিতর্কযোগ্য ব্যবহার।
রব


@ ডানকান সি হ্যালো ডানকান আমি প্রতিটি মডেলটিতে স্থির অবজেক্ট তৈরি করছি যাতে সঠিক অবস্থানের যে কোনও জায়গা থেকে আমি ডেটা পাই বা আপনার পথের কারণটি অনুসরণ করতে হবে এটি খুব সঠিক বলে মনে হচ্ছে।
বীরেন্দ্র সিং রাঠোর

@ বীরেন্দ্রসিংহঠোর, গ্লোবাল স্ট্যাটিক ভেরিয়েবলগুলি অ্যাপ্লিকেশন জুড়ে ডেটা ভাগ করার সবচেয়ে খারাপ উপায় possible তারা আপনার অ্যাপ্লিকেশন অংশগুলি একত্রে একত্রে জুড়ে দেয় এবং গুরুতর আন্তঃনির্ভরতা প্রবর্তন করে। এটি "খুব সঠিক" এর ঠিক বিপরীত।
ডানকান সি

@ ডানকানসি - এই প্যাটার্নটি কি কারেন্ট ইউজার অবজেক্টের জন্য কাজ করবে - মূলত এমন একক ব্যবহারকারী যিনি আপনার অ্যাপটিতে লগ ইন করেছেন? thx
টিম্পোন

9

সুইফট 4

সুইফটে ডেটা পাস করার জন্য অনেকগুলি পন্থা রয়েছে। এখানে আমি এর সেরা কয়েকটি পদ্ধতির যোগ করছি।

1) স্টোরিবোর্ড সেগু ব্যবহার করা

উত্স এবং গন্তব্য ভিউ কন্ট্রোলার এবং তদ্বিপরীত মধ্যে ডেটা পাস করার জন্য স্টোরিবোর্ড সেগগুলি খুব কার্যকর।

// If you want to pass data from ViewControllerB to ViewControllerA while user tap on back button of ViewControllerB.
        @IBAction func unWindSeague (_ sender : UIStoryboardSegue) {
            if sender.source is ViewControllerB  {
                if let _ = sender.source as? ViewControllerB {
                    self.textLabel.text = "Came from B = B->A , B exited"
                }
            }
        }

// If you want to send data from ViewControllerA to ViewControllerB
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if  segue.destination is ViewControllerB {
                if let vc = segue.destination as? ViewControllerB {
                    vc.dataStr = "Comming from A View Controller"
                }
            }
        }

2) ডেলিগেট পদ্ধতি ব্যবহার

ViewControllerD

//Make the Delegate protocol in Child View Controller (Make the protocol in Class from You want to Send Data)
    protocol  SendDataFromDelegate {
        func sendData(data : String)
    }

    import UIKit

    class ViewControllerD: UIViewController {

        @IBOutlet weak var textLabelD: UILabel!

        var delegate : SendDataFromDelegate?  //Create Delegate Variable for Registering it to pass the data

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            textLabelD.text = "Child View Controller"
        }

        @IBAction func btnDismissTapped (_ sender : UIButton) {
            textLabelD.text = "Data Sent Successfully to View Controller C using Delegate Approach"
            self.delegate?.sendData(data:textLabelD.text! )
            _ = self.dismiss(animated: true, completion:nil)
        }
    }

ভিউকন্ট্রোলারসি

    import UIKit

    class ViewControllerC: UIViewController , SendDataFromDelegate {

        @IBOutlet weak var textLabelC: UILabel!

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
        }

        @IBAction func btnPushToViewControllerDTapped( _ sender : UIButton) {
            if let vcD = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerD") as?  ViewControllerD  {
                vcD.delegate = self // Registring Delegate (When View Conteoller D gets Dismiss It can call sendData method
    //            vcD.textLabelD.text = "This is Data Passing by Referenceing View Controller D Text Label." //Data Passing Between View Controllers using Data Passing
                self.present(vcD, animated: true, completion: nil)
            }
        }

        //This Method will called when when viewcontrollerD will dismiss. (You can also say it is a implementation of Protocol Method)
        func sendData(data: String) {
            self.textLabelC.text = data
        }

    }

Googlers দের যারা যেমন সম্পূর্ণরূপে যেখানে Stackoverflow উত্তর 'সুইফট কোড স্নিপেট লাগাতে যেমন আমি, যেমন অধিকৃত মনে আপনি সবসময় জানতে যেখানে তারা অনুমান কোড যায় উচিত হিসেবে হারিয়ে যায় | কিন্তু আমি বিকল্প 1) থেকে পাঠাতে ব্যবহার ViewControllerAকরতে ViewControllerB। আমি শেষ কোঁকড়া ধনুর্বন্ধনী এর ঠিক ঠিক আগে আমার স্নিপেটটি ViewControllerA.swift( আমার ViewControllerA.swiftফাইলের নামই আসলে যেখানে আছে অবশ্যই আছে) আটকেছি। " prepare" আসলে প্রদত্ত শ্রেণিতে একটি বিশেষ অন্তর্নির্মিত পূর্ব-বিদ্যমান ফাংশন [যা কিছুই করে না], এজন্য আপনাকে overrideএটি করতে হবে " "
ভেলকুন

8

আরেকটি বিকল্প হ'ল নোটিফিকেশন সেন্টার (এনএসএনটিফিকেশন সেন্টার) এবং পোস্ট বিজ্ঞপ্তি ব্যবহার করা। এটি একটি খুব আলগা মিলন। কোনও বিজ্ঞপ্তির প্রেরককে কে শুনছে তা জানা বা যত্নের প্রয়োজন নেই। এটি কেবল একটি বিজ্ঞপ্তি পোস্ট করে এবং এটি সম্পর্কে ভুলে যায়।

এক-একাধিক বার্তা পাসের জন্য বিজ্ঞপ্তিগুলি ভাল, যেহেতু কোনও প্রদত্ত বার্তা শুনে শ্রোতাদের একটি স্বেচ্ছাসেবী সংখ্যা থাকতে পারে।


4
নোট করুন যে নোটিফিকেশন সেন্টার ব্যবহার করে কাপলিংয়ের পরিচয় হয় যা সম্ভবত খুব আলগা। এটি আপনার প্রোগ্রামের প্রবাহকে খুব কঠিন করে তুলতে পারে, তাই এটি যত্ন সহ ব্যবহার করা উচিত।
ডানকান সি

2

ডেটা কন্ট্রোলার সিনজেল্টন তৈরির পরিবর্তে আমি একটি ডেটা কন্ট্রোলার উদাহরণ তৈরি করতে এবং এটিকে পাস করার পরামর্শ দেব would নির্ভরতা ইনজেকশন সমর্থন করতে আমি প্রথমে একটি DataControllerপ্রোটোকল তৈরি করব :

protocol DataController {
    var someInt : Int {get set} 
    var someString : String {get set}
}

তারপরে আমি একটি SpecificDataController(বা যে কোনও নাম বর্তমানে উপযুক্ত হবে) শ্রেণি তৈরি করব:

class SpecificDataController : DataController {
   var someInt : Int = 5
   var someString : String = "Hello data" 
}

ViewControllerবর্গ তারপর একটি ক্ষেত্র রাখা থাকা উচিত dataController। লক্ষ্য করুন যে ধরণ dataControllerপ্রোটোকল DataController। এইভাবে ডেটা কন্ট্রোলার বাস্তবায়নগুলি পরিবর্তন করা সহজ:

class ViewController : UIViewController {
   var dataController : DataController?
   ...
}

এতে AppDelegateআমরা নিয়ন্ত্রণকারীর ভিউ সেট করতে পারি dataController:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if let viewController = self.window?.rootViewController as? ViewController {
        viewController.dataController =  SpecificDataController()
    }   
    return true
}

আমরা যখন অন্য কোনও ভিউ কন্ট্রোলারে চলে যাই তখন আমরা এটিকে পাস করতে পারি dataController:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    ...   
}

এখন যখন আমরা কোনও আলাদা টাস্কের জন্য ডেটা কন্ট্রোলারটি স্যুইচ আউট করতে চাই তখন আমরা এটি করতে পারি AppDelegateএবং ডেটা কন্ট্রোলার ব্যবহার করে এমন কোনও কোড পরিবর্তন করতে হবে না।

এটি অবশ্যই ওভারকিল হয় যদি আমরা কেবল একটি একক মানের কাছাকাছি যেতে চাই। এক্ষেত্রে এনএইচগ্রিফের উত্তর নিয়ে যাওয়া ভাল।

এই পদ্ধতির সাহায্যে আমরা যুক্তির অংশটি ফর্মটি পৃথক করতে পারি।


4
হ্যালো, এই পদ্ধতিটি পরিষ্কার, পরীক্ষামূলক এবং আমি ছোট অ্যাপ্লিকেশনগুলিতে বেশিরভাগ সময়ই কী ব্যবহার করি তবে বৃহত্তর ক্ষেত্রে যেখানে প্রতিটি উপাচার্য (সম্ভবত মূল উপাচার্য এমনকি নয়) এর নির্ভরতাও প্রয়োজন হতে পারে (যেমন, এই ক্ষেত্রে ডেটা নিয়ন্ত্রণকারী) প্রতিটি উপাচার্যকে নির্ভর করে কেবল এটি প্রায় পাস করার জন্য অপ্রয়োজনীয় মনে হয়। এছাড়াও, আপনি যদি ভিসির বিভিন্ন ধরণের (যেমন নিয়মিত ইউআইভিসি বনাম নেভিগেশনভিসি) ব্যবহার করেন তবে আপনাকে সেই নির্ভরশীলতা ভেরিয়েবল যুক্ত করার জন্য আপনাকে সেই বিভিন্ন ধরণের সাবক্লাস করতে হবে। আপনি কিভাবে এই কাছে যান?
রবার্তো কিউবা

1

@ ননগ্রিফ তাঁর দুর্দান্ত উত্তরে যেমন উল্লেখ করেছেন, ভিসি (দেখুন নিয়ন্ত্রকগণ) এবং অন্যান্য বস্তু একে অপরের সাথে যোগাযোগ করতে পারে এমন প্রচুর উপায় রয়েছে।

আমি আমার প্রথম উত্তরে যে তথ্য সিঙ্গেলটনটি উল্লেখ করেছি তা হ'ল সরাসরি যোগাযোগের চেয়ে বিশ্বব্যাপী রাষ্ট্র ভাগ করে নেওয়া এবং সংরক্ষণ করা সম্পর্কে আরও বেশি কিছু।

nhrif এর উত্তর আপনাকে সরাসরি উত্স থেকে গন্তব্য ভিসিতে প্রেরণ করতে দেয়। আমি জবাব হিসাবে উল্লেখ করেছি, গন্তব্য থেকে উত্স থেকে বার্তা প্রেরণ করাও সম্ভব।

প্রকৃতপক্ষে, আপনি বিভিন্ন দর্শন নিয়ন্ত্রকের মধ্যে একটি সক্রিয় একমুখী বা 2-উপায় চ্যানেল সেট আপ করতে পারেন। স্টোরিবোর্ড সেগু-এর মাধ্যমে যদি ভিউ কন্ট্রোলারগুলি লিঙ্কযুক্ত থাকে তবে লিঙ্কগুলি সেট আপ করার সময়টি সিদ্ধ পদ্ধতি প্রস্তুতি ফরওয়ারে রয়েছে।

আমার কাছে গিথুবে একটি নমুনা প্রকল্প রয়েছে যা শিশু হিসাবে 2 টি আলাদা টেবিল ভিউ হোস্ট করতে পিতামাতার ভিউ কন্ট্রোলার ব্যবহার করে। চাইল্ড ভিউ কন্ট্রোলারগুলি এম্বেড সেগগুলি ব্যবহার করে লিঙ্কযুক্ত এবং পিতামাতার ভিউ কন্ট্রোলার প্রস্তুতিফৌজ পদ্ধতিতে প্রতিটি ভিউ কন্ট্রোলারের সাথে 2-উপায় লিঙ্কগুলি আপ করে।

আপনি গিথুব (লিঙ্ক) এ প্রকল্পটি পেতে পারেন । আমি তবে এটি ওজেক্টিভ-সি-তে লিখেছি এবং এটিকে সুইফটে রূপান্তর করি নি, সুতরাং আপনি যদি উদ্দেশ্য-সি-তে স্বাচ্ছন্দ্য বোধ করেন না তবে এটি অনুসরণ করা কিছুটা কঠিন হতে পারে


1

সুইফট 3:

আপনার যদি চিহ্নিত স্টিগগুলি সহ স্টোরিবোর্ড থাকে:

func prepare(for segue: UIStoryboardSegue, sender: Any?)

যদিও আপনি বিভিন্ন ইউআইভিউউকন্ট্রোলারের মধ্যে নেভিগেশন সহ প্রোগ্রামগতভাবে সবকিছু করেন তবে পদ্ধতিটি ব্যবহার করুন:

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool)

দ্রষ্টব্য: আপনার ইউআইএনএভিগেশন নিয়ন্ত্রক তৈরি করার জন্য আপনাকে দ্বিতীয় উপায়ে ব্যবহার করতে, আপনি ইউআইভিউউইন কন্ট্রোলারদের উপর চাপ দিচ্ছেন, একজন প্রতিনিধি এবং প্রোটোকল ইউআইএনএভিগেশন কন্ট্রোলারডেলিগেটের সাথে এটি মেনে চলতে হবে:

   class MyNavigationController: UINavigationController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {

     // do what ever you need before going to the next UIViewController or back
     //this method will be always called when you are pushing or popping the ViewController

    }
}

21.

1

এটি নির্ভর করে আপনি কখন ডেটা পেতে চান।

আপনি যখনই চান ডেটা পেতে চাইলে সিঙ্গলটন প্যাটার্নটি ব্যবহার করতে পারেন। প্যাটার্ন ক্লাসটি অ্যাপ রানটাইমের সময় সক্রিয় থাকে। এখানে সিঙ্গেলটন প্যাটার্নের একটি উদাহরণ।

class AppSession: NSObject {

    static let shared = SessionManager()
    var username = "Duncan"
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        print(AppSession.shared.username)
    }
}

আপনি যদি কোনও পদক্ষেপের পরে ডেটা পেতে চান তবে নোটিফিকেশন সেন্টার ব্যবহার করতে পারেন।

extension Notification.Name {
    static let loggedOut = Notification.Name("loggedOut")
}

@IBAction func logoutAction(_ sender: Any) {
    NotificationCenter.default.post(name: .loggedOut, object: nil)
}

NotificationCenter.default.addObserver(forName: .loggedOut, object: nil, queue: OperationQueue.main) { (notify) in
    print("User logged out")
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.