প্যারেন্ট আইওএস থেকে কনটেইনার ভিউ কন্ট্রোলার অ্যাক্সেস করুন


203

আইওএস in-তে আমি নতুন কনটেইনার ভিউটি লক্ষ্য করেছি তবে কীভাবে নিয়ন্ত্রণযুক্ত ভিউ থেকে এটি নিয়ন্ত্রণকারী অ্যাক্সেস করবেন তা পুরোপুরি নিশ্চিত নই।

দৃশ্যপট:

উদাহরণ

আমি কনটেইনার ভিউ রাখে এমন ভিউ কন্ট্রোলার থেকে অ্যালার্ট ভিউ কন্ট্রোলারের লেবেলগুলি অ্যাক্সেস করতে চাই।

তাদের মধ্যে একটি উত্তেজনা আছে, আমি কি এটি ব্যবহার করতে পারি?


আধুনিক ধারক দর্শনগুলির জন্য এখানে সম্পূর্ণরূপে ব্যাখ্যা করা হয়েছে: স্ট্যাকওভারফ্লো.com
23403979

উত্তর:


362

হ্যাঁ, আপনি চাইল্ড ভিউ কন্ট্রোলার (এবং এর দৃশ্য এবং সংক্ষিপ্তসারগুলি) অ্যাক্সেস পেতে সেগ ব্যবহার করতে পারেন। alertview_embedস্টোরিবোর্ডে অ্যাট্রিবিউটস ইন্সপেক্টর ব্যবহার করে সেগটিকে একটি সনাক্তকারী (যেমন ) দিন। তারপরে প্যারেন্ট ভিউ কন্ট্রোলারকে (কনটেইনার দৃশ্যের সাথে এক জন) এই পদ্ধতিটি প্রয়োগ করুন:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   NSString * segueName = segue.identifier;
   if ([segueName isEqualToString: @"alertview_embed"]) {
       AlertViewController * childViewController = (AlertViewController *) [segue destinationViewController];
       AlertView * alertView = childViewController.view;
       // do something with the AlertView's subviews here...
   }
}

1
আমরা সেলগিজ করছি না? আমি কি এখানে কিছু মিস করছি ...?
অ্যাডাম ওয়েট

25
হ্যাঁ, একটি এম্বেড সেগ রয়েছে যা দ্বিতীয় ভিউ কন্ট্রোলারটিকে প্রথম দর্শনের নিয়ামক হিসাবে তৈরি করা হয়। প্রস্তুতিফেরত: এটি হওয়ার ঠিক আগে বলা হয়। আপনি এই সুযোগটি সন্তানের কাছে ডেটা প্রেরণ করতে, বা পরে ব্যবহারের জন্য সন্তানের একটি রেফারেন্স সঞ্চয় করতে পারেন। এছাড়াও বিকাশকারী.অ্যাপল.
পিটার ই

1
আহ্ ঠিক, ভিউটি লোড হয়ে যাওয়ার পরে 'দ্বিতীয় দর্শন নিয়ন্ত্রককে কি প্রথম ভিউ নিয়ন্ত্রকের সন্তানের তৈরি করা হয়'? ধন্যবাদ এটি এখন আরও অর্থবোধ করে। আমি এখন আমার প্রকল্পের সাথে নেই তবে পরে পরীক্ষা করব
অ্যাডাম ওয়েট

1
হুবহু, এটিকে ভিউডিডলডের আগে ডাকা হয়। ভিউডিডলয়েড পৌঁছে যাওয়ার পরে, পিতামাতা এবং সন্তানের সংযোগ হয়েছে এবং পিতা-মাতার মধ্যে [স্ব চাইল্ডভিউ কনট্রোলাররা] সমস্ত শিশু নিয়ন্ত্রকের একটি অ্যারে ফিরিয়ে দেবে (নীচে rdelmar এর উত্তর দেখুন)।
পিটার ই

2
আমি প্রস্তাবিত সমাধানে একটি সতর্কতা যুক্ত করব: (শিশু) গন্তব্য দেখার নিয়ন্ত্রকের দর্শন সম্পত্তিটি অ্যাক্সেস করার সময় খুব সাবধানতা অবলম্বন করুন: কিছু পরিস্থিতিতে এটির ভিডডিডলডটি সেখানে ডেকে আনা হবে এবং তারপরে আমি আগেই প্রয়োজনীয় সিগু ডেটা স্থাপনের পরামর্শ দেব I যাতে ভিউডিডলড নিরাপদে গুলি চালাতে পারে।
সর্বদা

56

আপনি কেবল self.childViewControllers.lastObjectএটির সাহায্যে (ধরে নিতে পারেন যে আপনার কেবলমাত্র একটি সন্তান রয়েছে, অন্যথায় ব্যবহার করুন objectAtIndex:)।


1
@ রাফেল ওলিভিরা, অগত্যা নয়। আপনার যদি একক ভিউতে একাধিক চাইল্ড কন্ট্রোলার থাকে তবে এটি পছন্দসই পদ্ধতি হবে। এটি আপনাকে একসাথে একাধিক পাত্রে সমন্বয় করতে দেয়। প্রস্তুতিফরসিগের কেবলমাত্র একক শিশু নিয়ামক হিসাবে এটি অভিনয় করছে তার উল্লেখ রয়েছে।
ফাইদো

2
@ ফাইডো, এবং 'সেগের জন্য প্রস্তুত' তে একাধিক কনটেইনার সমস্ত হ্যান্ডেল করতে সমস্যা কি?
গনজালেজ

1
(ভয়াবহতা!) আপনি যদি স্টোরিবোর্ড থেকে স্যুইচ করার সিদ্ধান্ত নেন বা সিকোয়াস ইত্যাদি ব্যবহার করবেন না, তাহলে আপনাকে কোড পরিবর্তন করতে হবে ইত্যাদি খনন করতে হবে
টম অ্যান্ডারসন

2
এটি আমার স্বাভাবিক পদ্ধতির, তবে এখন এটি আমার জন্য ক্র্যাশ হয়ে গেছে যেহেতু আমি childViewControllers"খুব শীঘ্রই" অ্যাক্সেস করছি
মাইজিড

24

সুইফ্ট প্রোগ্রামিংয়ের জন্য

আপনি এই মত লিখতে পারেন

var containerViewController: ExampleViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // you can set this name in 'segue.embed' in storyboard
    if segue.identifier == "checkinPopupIdentifierInStoryBoard" {
        let connectContainerViewController = segue.destinationViewController as ExampleViewController
        containerViewController = connectContainerViewController
    }
}

যদি বিবৃতিতে segueName পরে প্রশ্ন চিহ্ন জন্য ব্যবহার কি? "যদি সিগনাম?"
শ্রদ্ধেয়

18

prepareForSegueপদ্ধতির কাজ করে, কিন্তু এটি segue আইডেন্টিফায়ার যাদু স্ট্রিং উপর নির্ভর করে। সম্ভবত আরও ভাল উপায় আছে।

আপনি যদি ভিসির ক্লাসটি পরে থাকেন তা যদি আপনি জেনে থাকেন তবে আপনি কোনও গণিত সম্পত্তি দিয়ে খুব সুন্দর করে এটি করতে পারেন:

var camperVan: CamperVanViewController? {
  return childViewControllers.flatMap({ $0 as? CamperVanViewController }).first
  // This works because `flatMap` removes nils
}

এটি উপর নির্ভর করে childViewControllers। যদিও আমি সম্মত হচ্ছি যে প্রথমটির উপর নির্ভর করা ভঙ্গুর হতে পারে, আপনি যে শ্রেণীর সন্ধান করেছেন নামকরণ এটি বেশ শক্ত মনে হয়।


3
return childViewControllers.filter { $0 is CamperVanViewController }.firstএক লাইনে
অ্যাডাম

1
আমি তখন থেকে childViewControllers.flatMap({ $0 as? CamperVanViewController }).firstযা করেছি যা আমি মনে করি এটি আরও ভাল, যেহেতু এটি কাস্ট করে এবং কোনও নীল থেকে মুক্তি পায়।
সিম্পলজি

আপনি যদি একাধিক বার সেই ভিউ কন্ট্রোলার অ্যাক্সেস করতে চান তবে এটি সত্যিই ভাল সমাধান
গ্যাব্রিয়েল গনক্যাল্ভস

এটি হতাশ - এটি নির্দিষ্ট শ্রেণীর মধ্যে আপনার কেবল একটি থাকতে পারে এমন কোনও নির্দিষ্ট কারণ নেই। শনাক্তকারীদের অস্তিত্বই ঠিক তাই। কেবলমাত্র স্ট্যান্ডার্ড সূত্রটি অনুসরণ করুন ... স্ট্যাকওভারফ্লো
a/

শুধুমাত্র প্রথম উপাদান নিতে ফিল্টার করবেন না। শুধু ব্যবহার first(where:)childViewControllers.first(where: { $0 is CamperVanViewController })
আলেকজান্ডার - মনিকা পুনরায়

9

গণিত সম্পত্তি ব্যবহার করে সুইফট 3-এর একটি আপডেট উত্তর:

var jobSummaryViewController: JobSummaryViewController {
    get {
        let ctrl = childViewControllers.first(where: { $0 is JobSummaryViewController })
        return ctrl as! JobSummaryViewController
    }
}

এটি কেবলমাত্র বাচ্চাদের তালিকাকে প্রথম ম্যাচে না আসা পর্যন্ত পুনরাবৃত্তি করে।


8

self.childViewControllers যখন আপনার পিতামাতার কাছ থেকে নিয়ন্ত্রণ প্রয়োজন তখন আরও প্রাসঙ্গিক। উদাহরণস্বরূপ, যদি শিশু নিয়ন্ত্রণকারী একটি টেবিল ভিউ হয় এবং আপনি এটিকে জোর করে পুনরায় লোড করতে চান বা পিতামাতা ভিউ কন্ট্রোলারের কোনও বোতামের ট্যাপ বা অন্য কোনও ইভেন্টের মাধ্যমে কোনও সম্পত্তি পরিবর্তন করতে চান, আপনি চাইল্ডভিউ কনট্রোলারের উদাহরণটি অ্যাক্সেস করে এটি করতে পারেন, প্রিপারেসসিগের মাধ্যমে নয়। উভয়েরই বিভিন্ন উপায়ে তাদের অ্যাপ্লিকেশন রয়েছে।


2

ভিউ কন্ট্রোলারের ধরণে সুইফটের সুইচ স্টেটমেন্টটি ব্যবহার করার অন্য উপায় রয়েছে:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
  switch segue.destination
  {
    case let aViewController as AViewController:
      self.aViewController = aViewController
    case let bViewController as BViewController:
      self.bViewController = bViewController
    default:
      return
  }
}

1

আমি কোড ব্যবহার করি:

- (IBAction)showCartItems:(id)sender{ 
  ListOfCartItemsViewController *listOfItemsVC=[self.storyboard instantiateViewControllerWithIdentifier:@"ListOfCartItemsViewController"];
  [self addChildViewController:listOfItemsVC];
 }

1

যদি কেউ সুইফট ৩.০ খুঁজছেন ,

ভিউকন্ট্রোলার 1 , ভিউ কন্ট্রোলার 2 এবং এরপরে অ্যাক্সেসযোগ্য হবে।

let viewController1 : OneViewController!
let viewController2 : TwoViewController!

// Safety handling of optional String
if let identifier: String = segue.identifier {

    switch identifier {

    case "segueName1":
        viewController1 = segue.destination as! OneViewController
        break

    case "segueName2":
        viewController2 = segue.destination as! TwoViewController
        break

    // ... More cases can be inserted here ...

    default:
        // A new segue is added in the storyboard but not yet including in this switch
        print("A case missing for segue identifier: \(identifier)")
        break
    }

} else {
    // Either the segue or the identifier is inaccessible 
    print("WARNING: identifier in segue is not accessible")
}

1

জেনেরিক দিয়ে আপনি কিছু মিষ্টি জিনিস করতে পারেন। এখানে অ্যারের এক্সটেনশান:

extension Array {
    func firstMatchingType<Type>() -> Type? {
        return first(where: { $0 is Type }) as? Type
    }
}

তারপরে আপনি আপনার ভিউকন্ট্রোলারে এটি করতে পারেন:

var viewControllerInContainer: YourViewControllerClass? {
    return childViewControllers.firstMatchingType()!
}

0

আপনি এই মত লিখতে পারেন

- (IBAction)showDetail:(UIButton *)sender {  
            DetailViewController *detailVc = [self.childViewControllers firstObject];  
        detailVc.lable.text = sender.titleLabel.text;  
    }  
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.