ভিউ কন্ট্রোলারদের মধ্যে ডেটা পাস করা হচ্ছে


1372

আমি আইওএস এবং অবজেক্টিভ-সি এবং পুরো এমভিসি দৃষ্টান্তে নতুন এবং আমি নিম্নলিখিতটি নিয়ে আটকেছি:

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

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

আমি চারপাশে সার্ফ করে দেখেছি এবং কিছু লোক অ্যাপ প্রতিনিধিতে একটি অ্যারে ঘোষণা করে। আমি সিলেটলেটস সম্পর্কে কিছু পড়ি তবে এগুলি কী তা বুঝতে পারি না এবং আমি একটি ডেটা মডেল তৈরি করার বিষয়ে কিছু পড়েছি।

এটি সম্পাদন করার সঠিক উপায় কী হবে এবং আমি এটি কীভাবে করব?

উত্তর:


1683

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

আমি আশা করি এই উত্তরটি লোকেরা বুঝতে পারার পক্ষে যথেষ্ট স্পষ্ট এবং আমি কোনও কিছুই মিস করি নি।

ফরোয়ার্ড ডেটা পাসিং

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

এই উদাহরণস্বরূপ, আমরা ViewControllerAএবং করবViewControllerB

থেকে একটি BOOLমান পাস করার ViewControllerAজন্য ViewControllerBআমরা নিম্নলিখিতটি করব।

  1. মধ্যে ViewControllerB.hএকটি সম্পত্তি তৈরিBOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
  2. আপনি ViewControllerAএটি সম্পর্কে ViewControllerBএকটি বলার প্রয়োজন

    #import "ViewControllerB.h"

    তারপরে আপনি যেখানে ভিউটি লোড করতে চান। didSelectRowAtIndexবা কিছু IBActionআপনাকে ViewControllerBএনএভ স্ট্যাকের দিকে ধাক্কা দেওয়ার আগে আপনার সম্পত্তি সেট করতে হবে।

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.isSomethingEnabled = YES;
    [self pushViewController:viewControllerB animated:YES];

    এই সেট হবে isSomethingEnabledমধ্যে ViewControllerBথেকে BOOLমান YES

সেগগুলি ব্যবহার করে ডেটা ফরোয়ার্ডে পাস করা

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

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

সুতরাং একটি BOOLথেকে পাস ViewControllerAকরার জন্য ViewControllerBআমরা নিম্নলিখিতগুলি করব:

  1. মধ্যে ViewControllerB.hএকটি সম্পত্তি তৈরিBOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
  2. আপনি ViewControllerAএটি সম্পর্কে ViewControllerBএকটি বলার প্রয়োজন

    #import "ViewControllerB.h"
  3. থেকে একটি segue তৈরি করুন ViewControllerAথেকে ViewControllerBস্টোরিবোর্ড এবং এটি একটি আইডেন্টিফায়ার দিতে, এই উদাহরণে আমরা এটা ডাকবো"showDetailSegue"

  4. এর পরে, আমাদের ViewControllerAযে পদ্ধতিটি বলা হয় তার সাথে আমাদের সেই পদ্ধতিটি যুক্ত করতে হবে যখন কোনও সিগ সম্পাদন করা হয়, এর কারণে আমাদের সনাক্ত করতে হবে কোনটি সেগু ডাকা হয়েছিল এবং তারপরে কিছু করা উচিত। আমাদের উদাহরণে আমরা যাচাই করব "showDetailSegue"এবং যদি এটি সম্পাদিত হয় তবে আমরা আমাদের BOOLমানটি পাস করবViewControllerB

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
            controller.isSomethingEnabled = YES;
        }
    }

    আপনার মতামত একটি নেভিগেশন কন্ট্রোলারে এম্বেড থাকলে আপনার উপরের পদ্ধতিটি কিছুটা নীচে পরিবর্তন করতে হবে

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
            controller.isSomethingEnabled = YES;
        }
    }

    এই সেট হবে isSomethingEnabledমধ্যে ViewControllerBথেকে BOOLমান YES

ডেটা পিছনে পাস করা

থেকে ডেটা ফিরে প্রেরণ করার জন্য ViewControllerBকরতে ViewControllerAআপনি ব্যবহার করতে হবে প্রোটোকল এবং প্রতিনিধিদের বা ব্লক , আধুনিক callbacks জন্য একটি ঢিলেঢালাভাবে মিলিত প্রক্রিয়া হিসেবে ব্যবহার করা যাবে।

এটি করার জন্য আমরা ViewControllerAএকটি প্রতিনিধি করব ViewControllerB। এটি ViewControllerBআবার কোনও বার্তা প্রেরণ করতে দেয়ViewControllerA আমাদের ডেটা ফেরত প্রেরণে সক্ষম ।

এর ViewControllerAপ্রতিনিধি হওয়ার জন্য ViewControllerBঅবশ্যই ViewControllerBআমাদের নির্দিষ্ট করা প্রোটোকলের সাথে সঙ্গতিপূর্ণ থাকতে হবে। এটি ViewControllerAকোন পদ্ধতিগুলি প্রয়োগ করতে হবে তা তা বলে ।

  1. ইন ViewControllerB.h, এর নীচে #import, তবে উপরে @interfaceআপনি প্রোটোকলটি নির্দিষ্ট করবেন।

    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate <NSObject>
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
    @end
  2. এরপরেও ViewControllerB.hআপনাকে একটি delegateসম্পত্তি সেটআপ করতে হবে এবং সংশ্লেষ করতে হবেViewControllerB.m

    @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
  3. ইন ViewControllerBআমরা delegateযখন আমরা ভিউ কন্ট্রোলারটিকে পপ করি তখন একটি বার্তা কল করি।

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
  4. এটা জন্য ViewControllerB। এখন ViewControllerA.h, ViewControllerAআমদানি করতে বলুন ViewControllerBএবং এর প্রোটোকল অনুসারে।

    #import "ViewControllerB.h"
    
    @interface ViewControllerA : UIViewController <ViewControllerBDelegate>
  5. ইন ViewControllerA.mআমাদের প্রোটোকল থেকে নিম্নোক্ত পদ্ধতি বাস্তবায়ন

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
  6. ঠেলাঠেলি আগে viewControllerBগৌণ স্ট্যাক আমরা বলতে চাই ViewControllerBযে ViewControllerAঅন্যথায় আমরা একটি ত্রুটি পাবেন, তার প্রতিনিধি নেই।

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];

তথ্যসূত্র

  1. ভিউ কন্ট্রোলার প্রোগ্রামিং গাইডের মধ্যে অন্যান্য ভিউ কন্ট্রোলারের সাথে যোগাযোগের জন্য ডেলিগেশন ব্যবহার করা
  2. প্রতিনিধি প্যাটার্ন

এনএসনিটিফিকেশন কেন্দ্র এটি ডেটা পাস করার অন্য উপায়।

// add observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"handleDeepLinking" object:nil];

-(void) handleDeepLinking:(NSNotification *) notification {
    id someObject = notification.object // some custom object that was passed with notification fire.
}

// post notification
id someObject;
[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeepLinking" object:someObject];

এক শ্রেণি থেকে অন্য শ্রেণিতে ডেটা পাঠানো (একটি শ্রেণি যে কোনও নিয়ামক, নেটওয়ার্ক / সেশন ম্যানেজার, ইউআইভিউ সাবক্লাস বা অন্য কোনও শ্রেণীর হতে পারে)

ব্লকগুলি বেনামে ফাংশন।

এই উদাহরণটি কন্ট্রোলার বি থেকে নিয়ন্ত্রণকারী এ তে পাস করে passes

একটি ব্লক সংজ্ঞায়িত

@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h

ব্লক হ্যান্ডলার (শ্রোতা) যুক্ত করুন যেখানে আপনার একটি মান প্রয়োজন (উদাহরণস্বরূপ আপনার নিজের এপিআই প্রতিক্রিয়া নিয়ন্ত্রণের মধ্যে প্রয়োজন বা আপনার A তে কনট্রোলারবি ডেটা প্রয়োজন)

// in ContollerA.m

- (void)viewDidLoad {
    [super viewDidLoad];
    __unsafe_unretained typeof(self) weakSelf = self;
    self.selectedVoucherBlock = ^(NSString *voucher) {
        weakSelf->someLabel.text = voucher;
    };
}

কন্ট্রোলার বি

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
    [self.navigationController pushViewController:vc animated:NO];

ফায়ার ব্লক

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: 
(NSIndexPath *)indexPath {
    NSString *voucher = vouchersArray[indexPath.row];
    if (sourceVC.selectVoucherBlock) {
        sourceVC.selectVoucherBlock(voucher);
    }
    [self.navigationController popToViewController:sourceVC animated:YES];
}

ব্লকগুলির জন্য আরেকটি কার্যকারী উদাহরণ


24
আমাদেরও কি @class ViewControllerB;@ প্রোটোকল সংজ্ঞা উপরে রাখতে হবে? তা ছাড়া আমার লাইনে ViewControllerB উপর একটি "প্রত্যাশিত টাইপ" ত্রুটি পাবেন: - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item; মধ্যে @protocolঘোষণা
অ্যালান-P

4
এটি দুর্দান্ত কাজ করে। অ্যালান-পি যেমন বলেছে, @ ক্লাস ভিউ কন্ট্রোলারবি লিখতে ভুলবেন না; প্রোটোকলের উপরে অন্যথায় আপনি "প্রত্যাশিত একটি ধরণের" ত্রুটি পাবেন।
অ্যান্ড্রু ডেভিস

6
ফিরে যাওয়ার জন্য আপনার প্রতিনিধিদের দরকার নেই, কেবল আনইন্ড ব্যবহার করুন।
ম্যালহাল

4
আমি যখন "ভিউকন্ট্রোলারবি.ডিলেগেট = স্ব" রেখেছি; ভিউ কন্ট্রোলারবিতে আমি একটি ত্রুটি পাচ্ছি। 'ভিউকন্ট্রোলারবিবি * কনস্ট __স্ট্রং' বেমানান টাইপ থেকে 'আইডি <ভিউকন্ট্রোলার বি ডেলিগেট>' অর্পণ করা, আমি নিশ্চিত না যে আমি কী ভুল করছি। কেউ সাহায্য করতে পারেন? প্লাস আমাকে পরিবর্তন করতে হয়েছিল: initWithNib -> initWithNibName।
uplearnedu.com

4
আপনি যদি NavigationControllerব্যবহার করেন তবে [self.navigationController pushViewController:viewController animated:YES];পরিবর্তে আপনাকে ব্যবহার করতে হবে[self pushViewController:viewControllerB animated:YES];
নাজির

192

দ্রুতগতি

এখানে এবং স্ট্যাকওভারফ্লো এর আশেপাশে প্রচুর সংখ্যক ব্যাখ্যা রয়েছে, তবে আপনি যদি শিক্ষানবিশ হয়ে থাকেন তবে কাজ করার জন্য কিছু বেসিক পাওয়ার চেষ্টা করছেন, এই ইউটিউব টিউটোরিয়ালটি দেখার চেষ্টা করুন (এটি আমাকে কীভাবে এটি করতে হয় তা অবশেষে বুঝতে সাহায্য করেছিল)।

পরবর্তী ভিউ কন্ট্রোলারের কাছে ডেটা এগিয়ে দেওয়া

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

এখানে চিত্র বর্ণনা লিখুন

ইন্টারফেস বিল্ডারে স্টোরিবোর্ড লেআউট তৈরি করুন। সেগুটি তৈরি করতে, আপনি কেবল Controlবোতামটি ক্লিক করুন এবং দ্বিতীয় ভিউ নিয়ন্ত্রকের কাছে টানুন।

প্রথম দেখুন নিয়ামক

ফার্স্ট ভিউ কন্ট্রোলারের জন্য কোডটি

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    // This function is called before the segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // get a reference to the second view controller
        let secondViewController = segue.destination as! SecondViewController

        // set a variable in the second view controller with the String to pass
        secondViewController.receivedString = textField.text!
    }

}

দ্বিতীয় দেখুন নিয়ামক

এবং দ্বিতীয় ভিউ কন্ট্রোলারের কোডটি

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    // This variable will hold the data being passed from the First View Controller
    var receivedString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Used the text from the First View Controller to set the label
        label.text = receivedString
    }

}

ভুলে যাবেন না

  • জন্য কারেন্টের হুক আপ UITextFieldএবংUILabel
  • আইবিতে যথাযথ সুইফ্ট ফাইলগুলিতে প্রথম এবং দ্বিতীয় দেখুন নিয়ন্ত্রকদের সেট করুন।

আগের ভিউ কন্ট্রোলারের কাছে ডেটা পাঠানো

দ্বিতীয় দর্শন নিয়ন্ত্রক থেকে প্রথম ভিউ নিয়ন্ত্রকের কাছে ডেটা পাঠাতে, আপনি একটি প্রোটোকল এবং একটি প্রতিনিধি ব্যবহার করেন । এই প্রক্রিয়াটি সত্ত্বেও এই ভিডিওটি একটি খুব স্পষ্ট হাঁটা:

নীচে ভিডিওর উপর ভিত্তি করে একটি উদাহরণ দেওয়া হয়েছে (কয়েকটি সংশোধন সহ)।

এখানে চিত্র বর্ণনা লিখুন

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

প্রথম দেখুন নিয়ামক

ফার্স্ট ভিউ কন্ট্রোলারের জন্য কোডটি

import UIKit

class FirstViewController: UIViewController, DataEnteredDelegate {

    @IBOutlet weak var label: UILabel!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondViewController" {
            let secondViewController = segue.destination as! SecondViewController
            secondViewController.delegate = self
        }
    }

    func userDidEnterInformation(info: String) {
        label.text = info
    }
}

আমাদের কাস্টম ব্যবহার নোট করুন DataEnteredDelegate প্রোটোকল ।

সেকেন্ড ভিউ কন্ট্রোলার এবং প্রোটোকল

দ্বিতীয় দর্শন নিয়ন্ত্রকের জন্য কোডটি

import UIKit

// protocol used for sending data back
protocol DataEnteredDelegate: AnyObject {
    func userDidEnterInformation(info: String)
}

class SecondViewController: UIViewController {

    // making this a weak variable so that it won't create a strong reference cycle
    weak var delegate: DataEnteredDelegate? = nil

    @IBOutlet weak var textField: UITextField!

    @IBAction func sendTextBackButton(sender: AnyObject) {

        // call this method on whichever class implements our delegate protocol
        delegate?.userDidEnterInformation(info: textField.text!)

        // go back to the previous view controller
        _ = self.navigationController?.popViewController(animated: true)
    }
}

নোট করুন যে protocol ভিউ কন্ট্রোলার শ্রেণীর বাইরে।

এটাই. এখন অ্যাপ্লিকেশন চালানো আপনার দ্বিতীয় ভিউ নিয়ন্ত্রক থেকে প্রথমটিতে ডেটা ফেরত পাঠাতে সক্ষম হওয়া উচিত।


সাম্প্রতিকতম কিছু সুইফ্ট আপডেট দেওয়া, এটি এখনও বাস্তবায়নের জন্য সাধারণ প্যাটার্ন?
পাইফুসকো

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

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

1
@ হিমাংশু, প্রথমে দ্বিতীয় দেখার নিয়ামকের একটি রেফারেন্স পান। তারপরে এতে থাকা সর্বজনীন পরিবর্তনশীল আপডেট করুন।
সুরগাচ

8
@Honey। আমি মনে করি "প্রতিনিধি" শব্দটি বিভ্রান্তিকর। আমাকে "কর্মী" শব্দটি ব্যবহার করুন। "কর্মী" (প্রথম দেখার নিয়ামক) "বস" (দ্বিতীয় দর্শন নিয়ামক) যা করতে বলে তা যা করে। "বস" জানেন না এর "কর্মী" কে হবেন; এটা যে কেউ হতে পারে। সুতরাং প্রথম দৃশ্যের নিয়ামক ("কর্মী" শ্রেণি) এ বলা হয়েছে, আমি আপনার "কর্মী" হব। আপনি আমাকে লেবেলে কী লিখবেন তা বলুন এবং আমি এটি আপনার জন্য করব। সুতরাং, এর secondViewController.delegate = selfঅর্থ "আমি বসের কর্মী হতে সম্মত" " অন্য উত্তর এবং আরও ব্যাখ্যা জন্য এই উত্তর দেখুন ।
সুরগাচ

136

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

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


95

বিভিন্ন উপায় রয়েছে যার মাধ্যমে আইওএসে একটি পৃথক শ্রেণিতে একটি ডেটা প্রাপ্ত করা যায়। উদাহরণ স্বরূপ -

  1. অন্য শ্রেণীর বরাদ্দের পরে সরাসরি সূচনা।
  2. ডেলিগেশন - ডেটা ফেরত দেওয়ার জন্য
  3. বিজ্ঞপ্তি - একসাথে একাধিক ক্লাসে ডেটা সম্প্রচারের জন্য
  4. ভিতরে সংরক্ষণ করা হচ্ছে NSUserDefaultsএটি অ্যাক্সেস করার জন্য পরে
  5. একক ক্লাস
  6. ডাটাবেস এবং অন্যান্য স্টোরেজ মেকানিজম যেমন প্লিস্ট ইত্যাদি,

তবে বর্তমান শ্রেণিতে যার বরাদ্দ করা হয় এমন একটি আলাদা শ্রেণীর কাছে একটি মান পাস করার সরল দৃশ্যের জন্য, সবচেয়ে সাধারণ এবং পছন্দের পদ্ধতিটি বরাদ্দের পরে মূল্যগুলির প্রত্যক্ষ স্থাপনা হবে। এটি নিম্নলিখিত হিসাবে সম্পন্ন করা হয়:

আমরা এটি দুটি নিয়ন্ত্রণকারী - কন্ট্রোলার 1 এবং কন্ট্রোলার 2 ব্যবহার করে বুঝতে পারি

ধরুন কন্ট্রোলার 1 ক্লাসে আপনি কন্ট্রোলার 2 অবজেক্ট তৈরি করতে চান এবং স্ট্রিংয়ের মান পাস করার সাথে এটি চাপুন। এটি এটি হিসাবে করা যেতে পারে:

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj passValue:@"String"];
    [self pushViewController:obj animated:YES];
}

কন্ট্রোলার 2 শ্রেণি প্রয়োগের ক্ষেত্রে এই ফাংশনটি হবে:

@interface Controller2  : NSObject

@property (nonatomic , strong) NSString* stringPassed;

@end

@implementation Controller2

@synthesize stringPassed = _stringPassed;

- (void) passValue:(NSString *)value {

    _stringPassed = value; //or self.stringPassed = value
}

@end

আপনি সরাসরি কন্ট্রোলার 2 শ্রেণীর বৈশিষ্ট্যগুলি ঠিক একইভাবে সেট করতে পারেন:

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj setStringPassed:@"String"];  
    [self pushViewController:obj animated:YES];
}

একাধিক মান পাস করতে আপনি একাধিক পরামিতি ব্যবহার করতে পারেন যেমন: -

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passValue:@“String1 andValues:objArray withDate:date]; 

অথবা আপনার যদি সাধারণ বৈশিষ্ট্যের সাথে সম্পর্কিত 3 টিরও বেশি পরামিতিগুলি পাস করতে হয় তবে আপনি একটি মডেল শ্রেণিতে মান সংরক্ষণ করতে পারেন এবং সেই মডেলটি পরবর্তী শ্রেণিতে পাস করতে পারেন

ModelClass *modelObject = [[ModelClass alloc] init]; 
modelObject.property1 = _property1;
modelObject.property2 = _property2;
modelObject.property3 = _property3;

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passmodel: modelObject];

সংক্ষিপ্তভাবে যদি আপনি চান -

1) set the private variables of the second class initialise the values by calling a custom function and passing the values.
2) setProperties do it by directlyInitialising it using the setter method.
3) pass more that 3-4 values related to each other in some manner , then create a model class and set values to its object and pass the object using any of the above process.

আশাকরি এটা সাহায্য করবে


84

আরও গবেষণার পরে মনে হয়েছিল প্রোটোকলস এবং ডেলিগেটস হ'ল অ্যাপল এটির সঠিক উপায়।

আমি এই উদাহরণটি ব্যবহার করে শেষ করেছি

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

ভাল কাজ করে এবং আমাকে আমার মতামতের মাঝে একটি স্ট্রিং এবং একটি অ্যারে এগিয়ে এবং পিছনে যেতে দেয়।

সব আপনার সাহায্যের জন্য ধন্যবাদ


3
প্রোটোকল এবং প্রতিনিধি ব্যবহার করবেন না, কেবল আনইন্ড ব্যবহার করুন।
ম্যালহাল

1
@মালহল আপনি যদি স্টোরিবোর্ড ব্যবহার না করেন ??
ইভান আর

আমি অকেজো প্রোটোকল এবং প্রতিনিধিদেরও ঘৃণা করি। @মালহাল
ডনসং

@ ইভানআর আপনি কোডগুলিতে সেগগুলি তৈরি করতে এবং সম্পাদন করতে পারেন। ইহা সব একই রকম.
ডনসং

1
মূলত এই পৃষ্ঠার পুরো QA হ'ল "ধারক দর্শনের আগের দিনগুলি থেকে"। আপনি কখনও মিলিয়ন বছরে প্রোটোকল বা প্রতিনিধিদের নিয়ে বিরক্ত করবেন না। আপনি যে কোনও স্ক্রিনে প্রতিটি ছোট্ট কাজই হউক না কেন একটি ধারক দর্শন, সুতরাং, প্রশ্নটি আসলেই আর বিদ্যমান নেই - আপনার কাছে ইতিমধ্যে সমস্ত ধারক দর্শন থেকে "উপরে এবং নীচে" সমস্ত উল্লেখ রয়েছে।
ফ্যাটি

66

পাসিং ব্লকগুলির সাথে আমি সবচেয়ে সহজ এবং সবচেয়ে মার্জিত সংস্করণ পাই। আসুন এমন ভিউ কন্ট্রোলারের নাম দিন যা প্রত্যাশিত ডেটার জন্য "এ" এবং প্রত্যাবর্তন ভিউ নিয়ামককে "বি" হিসাবে অপেক্ষা করে। এই উদাহরণে আমরা 2 টি মান পেতে চাই: টাইপ 1 এর প্রথম এবং টাইপ 2 এর দ্বিতীয়।

ধরে নেওয়া যাক আমরা স্টোরিবোর্ড ব্যবহার করি, প্রথম নিয়ামক কলগব্যাক ব্লক সেট করে, উদাহরণস্বরূপ সেগ প্রস্তুতির সময়:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController isKindOfClass:[BViewController class]])
    {
        BViewController *viewController = segue.destinationViewController;

        viewController.callback = ^(Type1 *value1, Type2 *value2) {
            // optionally, close B
            //[self.navigationController popViewControllerAnimated:YES];

            // let's do some action after with returned values
            action1(value1);
            action2(value2);
        };

    }
}

এবং "বি" ভিউ কন্ট্রোলারের কলব্যাক সম্পত্তি, বিভিউকন্ট্রোললিআর। ঘোষণা করতে হবে:

// it is important to use "copy"
@property (copy) void(^callback)(Type1 *value1, Type2 *value2);

BViewController.m বাস্তবায়ন ফাইলের চেয়ে আমরা আমাদের কলব্যাক ফেরত দেওয়ার জন্য পছন্দসই মানগুলি পাওয়ার পরে কল করতে হবে:

if (self.callback)
    self.callback(value1, value2);

একটি জিনিস মনে রাখবেন যে ব্লকটি ব্যবহার করার জন্য প্রায়শই এখানে বর্ণিত মত শক্তিশালী এবং __ উইক রেফারেন্স পরিচালনা করা প্রয়োজন


আলাদা সম্পত্তি হওয়ার চেয়ে কলব্যাক ব্লকের পরামিতি কেন হবে না?
টিমুইন

56

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

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

মূল পোস্টার এছাড়াও সম্পর্কে জিজ্ঞাসা Singletons এবং ব্যবহারের AppDelegate । এই প্রশ্নের উত্তর দেওয়া দরকার।

এই প্রশ্নটি দেখার জন্য অন্য যে কোনও ব্যক্তিকে সহায়তা করার জন্য, যিনি পুরো উত্তর চান, আমি এটি সরবরাহ করার চেষ্টা করছি going

অ্যাপ্লিকেশন পরিস্থিতি

অত্যন্ত অনুমানমূলক, বিমূর্ত আলোচনা করার পরিবর্তে এটি কংক্রিটের প্রয়োগগুলি মনে রাখতে সহায়তা করে। দ্বি-দর্শন-নিয়ামক পরিস্থিতি এবং আরও দ্বিগুণ-দেখার-নিয়ামক পরিস্থিতিকে সংজ্ঞায়িত করতে সহায়তা করতে আমি দুটি কংক্রিটের অ্যাপ্লিকেশন পরিস্থিতি সংজ্ঞায়িত করতে যাচ্ছি।

পরিস্থিতি এক: সর্বাধিক দু'জন ভিউ কন্ট্রোলারের কাছে তথ্য ভাগ করে নেওয়া দরকার। চিত্রটি দেখুন।

মূল সমস্যার ডায়াগ্রাম

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

পরিস্থিতি দুটি : দু'জনের অধিক ভিউ কন্ট্রোলারের একই তথ্য ভাগ করা দরকার। চিত্র দুটি দেখুন।

হোম জায় অ্যাপ্লিকেশন ডায়াগ্রাম

অ্যাপ্লিকেশনটিতে চারটি ভিউ কন্ট্রোলার রয়েছে। এটি হোম তালিকা পরিচালনার জন্য একটি ট্যাব-ভিত্তিক অ্যাপ্লিকেশন। তিনটি দর্শনা নিয়ন্ত্রক একই উপাত্তের পৃথকভাবে ফিল্টার করা ভিউগুলি উপস্থাপন করেন:

  • ViewControllerA - বিলাসবহুল আইটেম
  • ভিউকন্ট্রোলারবি - অ-বিমাযুক্ত আইটেম
  • ভিউকন্ট্রোলারসি - পুরো হোম ইনভেন্টরি
  • ViewControllerD - নতুন আইটেম ফর্ম যোগ করুন

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

যেহেতু সমস্ত ভিউ কন্ট্রোলারকে একই ডেটা ভাগ করা দরকার, চারটি ভিউ কন্ট্রোলারকে সিঙ্ক্রোনাইজেশনে থাকা দরকার, এবং তাই যখনই কোনও একক দর্শন নিয়ামক অন্তর্নিহিত ডেটা পরিবর্তন করে তখন অন্য সমস্ত ভিউ কন্ট্রোলারের সাথে কিছুটা যোগাযোগের প্রয়োজন হয়। এটি মোটামুটি সুস্পষ্ট হওয়া উচিত যে আমরা প্রতিটি দৃশ্যের নিয়ামককে এই দৃশ্যে একে অপরের ভিউ নিয়ন্ত্রকের সাথে সরাসরি যোগাযোগ করতে চাই না। যদি এটি সুস্পষ্ট না হয়, বিবেচনা করুন আমাদের যদি 20 টি ভিন্ন ভিউ কন্ট্রোলার থাকে (কেবল 4 এর চেয়ে বেশি)। অন্য 19 টি ভিউ কন্ট্রোলারের যেকোন সময় কোনও এক दृष्य নিয়ামক কোনও পরিবর্তন করলে তার প্রত্যেককে অবহিত করা কতটা কঠিন এবং ত্রুটি-ঝুঁকির বিষয় হতে পারে?

সমাধানগুলি: প্রতিনিধি এবং পর্যবেক্ষক প্যাটার্ন এবং সিঙ্গললেটস

এক দৃশ্যে, আমাদের কাছে বেশ কয়েকটি কার্যকর সমাধান রয়েছে, যেমন অন্যান্য উত্তরগুলি দিয়েছে

  • segues
  • প্রতিনিধিদের
  • সরাসরি দেখুন নিয়ন্ত্রকদের উপর বৈশিষ্ট্য নির্ধারণ
  • এনএসউসারডেফাল্টস (আসলে একটি দুর্বল পছন্দ)

দুটি দৃশ্যে, আমাদের অন্যান্য কার্যকর সমাধান রয়েছে:

  • পর্যবেক্ষক প্যাটার্ন
  • Singletons

একটি সিঙ্গলটন একটি শ্রেণীর উদাহরণ, সেই উদাহরণটি তার জীবদ্দশায় অস্তিত্বের একমাত্র উদাহরণ। এটি একটি একক দৃষ্টিকোণ থেকে একটি সিঙ্গলটন তার নাম পেয়েছে। সাধারণত বিকাশকারীরা যারা সিলেটলেট ব্যবহার করেন তাদের অ্যাক্সেসের জন্য বিশেষ শ্রেণীর পদ্ধতি রয়েছে।

+ (HouseholdInventoryManager*) sharedManager; {
    static dispatch_once_t onceQueue;
    static HouseholdInventoryManager* _sharedInstance;

    // dispatch_once is guaranteed to only be executed once in the
    // lifetime of the application
    dispatch_once(&onceQueue, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

এখন যেহেতু আমরা বুঝতে পারছি যে একটি সিঙ্গলটন কী, তাই সিঙ্গলটন পর্যবেক্ষক প্যাটার্নে কীভাবে ফিট হয় তা আলোচনা করা যাক। একটি অবজেক্টের জন্য অন্য অবজেক্টের পরিবর্তনের প্রতিক্রিয়া জানাতে পর্যবেক্ষক প্যাটার্ন ব্যবহার করা হয়। দ্বিতীয় দৃশ্যে, আমাদের চারটি পৃথক ভিউ কন্ট্রোলার রয়েছে, যারা সকলেই অন্তর্নিহিত ডেটার পরিবর্তনের বিষয়ে জানতে চান। "অন্তর্নিহিত ডেটা" একক উদাহরণ, একটি সিঙ্গলটনের অন্তর্গত। "পরিবর্তনগুলি সম্পর্কে জানুন" সিঙ্গলটনে করা পরিবর্তনগুলি পর্যবেক্ষণ করে সম্পন্ন হয়।

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

#import <Foundation/Foundation.h>

@class JGCHouseholdInventoryItem;

@interface HouseholdInventoryManager : NSObject
/*!
 The global singleton for accessing application data
 */
+ (HouseholdInventoryManager*) sharedManager;


- (NSArray *) entireHouseholdInventory;
- (NSArray *) luxuryItems;
- (NSArray *) nonInsuredItems;

- (void) addHouseholdItemToHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) editHouseholdItemInHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) deleteHoueholdItemFromHomeInventory:(JGCHouseholdInventoryItem*)item;
@end

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

  • কী-মান-পর্যবেক্ষণ (কেভিও)
  • NSNotificationCenter।

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

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

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

তথ্যসূত্র


41

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

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

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

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

// Prepare the destination view controller by passing it the input we want it to work on
// and the results we will look at when the user has navigated back to this controller's view.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results
     // by virtue of both controllers having a pointer to the same object.
     andResults:self.resultsFromNextController];
}

এই দ্বিতীয় উদাহরণটি দ্বিতীয় আর্গুমেন্টের জন্য একটি কলব্যাক ব্লক পাস করে দেখায়। আমি ব্লকগুলি ব্যবহার করতে পছন্দ করি কারণ এটি উত্স - উচ্চ স্তরের উত্সে প্রাসঙ্গিক বিশদ এক সাথে রাখে।

// Prepare the destination view controller by passing it the input we want it to work on
// and the callback when it has done its work.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results.
     resultsBlock:^(id results) {
         // This callback could be as involved as you like.
         // It can use Grand Central Dispatch to have work done on another thread for example.
        [self setResultsFromNextController:results];
    }];
}

41

ভিউকন্ট্রোলার 2 (গন্তব্য) থেকে ভিউকন্ট্রোলার 1 (উত্স) এ ডেটা ফেরত পাঠানো আরও আকর্ষণীয় বিষয়। ধরে নিচ্ছি যে আপনি স্টোরিবোর্ডটি ব্যবহার করেছেন এটি আমার কাছে পাওয়া সমস্ত উপায়:

  • প্রতিনিধি
  • প্রজ্ঞাপন
  • ব্যবহারকারী ডিফল্ট
  • একক বস্তু

সেগুলি এখানে ইতিমধ্যে আলোচনা করা হয়েছিল।

আমি আরও কিছু উপায় আছে পাওয়া গেছে:

ব্লক কলব্যাক ব্যবহার:

prepareForSegueভিসি 1 এ পদ্ধতিতে এটি ব্যবহার করুন

NextViewController *destinationVC = (NextViewController *) segue.destinationViewController;
[destinationVC setDidFinishUsingBlockCallback:^(NextViewController *destinationVC)
{
    self.blockLabel.text = destination.blockTextField.text;
}];

স্টোরিবোর্ডগুলি আনওয়াইন্ড ব্যবহার করুন (প্রস্থান করুন)

ভিসি 1 তে একটি ইউআইএসটিরিবোর্ডসাইগ যুক্তি দিয়ে একটি পদ্ধতি প্রয়োগ করুন:

-(IBAction)UnWindDone:(UIStoryboardSegue *)segue { }

স্টোরিবোর্ডে উপাচার্যের সবুজ প্রস্থান বোতামে (আনওয়াইন্ড) "রিটার্ন" বোতামটি চাপান। এখন আপনার কাছে একটি সিগ রয়েছে যে "ফিরে যায়" সুতরাং আপনি ভিসি 2 এর প্রস্তুতিমূলক ক্ষেত্রে গন্তব্যভিউকন্ট্রোলার সম্পত্তিটি ব্যবহার করতে এবং ভিসি 1 এর কোনও সম্পত্তি ফিরে যাওয়ার আগে পরিবর্তন করতে পারেন।

  • স্টোরিবোর্ডগুলি আনওয়াইন্ড (প্রস্থান) ব্যবহারের আরেকটি বিকল্প - আপনি ভিসি 1 তে যে পদ্ধতিটি লিখেছেন তা ব্যবহার করতে পারেন

    -(IBAction)UnWindDone:(UIStoryboardSegue *)segue {
        NextViewController *nextViewController = segue.sourceViewController;
        self.unwindLabel.text = nextViewController.unwindPropertyPass;
    } 

    এবং ভিসি 1 এর রেফারফেরসেগিতে আপনি যে কোনও সম্পত্তি ভাগ করতে চান তা পরিবর্তন করতে পারেন।

উভয় অনাইন্ড অপশনেই আপনি বোতামটির ট্যাগ বৈশিষ্ট্যটি সেট করতে পারেন এবং এটি প্রস্তুতিফেরুসে চেক করতে পারেন।

আশা করি আমি আলোচনায় কিছু যুক্ত করেছি।

:) চিয়ার্স


40

ডেটা ভাগ করার জন্য একাধিক পদ্ধতি রয়েছে।

  1. আপনি সর্বদা ব্যবহার করে ডেটা ভাগ করতে পারেন NSUserDefaults। আপনার পছন্দের একটি কী NSUserDefaultসম্পর্কিত আপনি যে মানটি ভাগ করতে চান তা সেট করুন এবং পরবর্তী ভিউ কন্ট্রোলারে সেই কীটির সাথে সম্পর্কিত থেকে মানটি পাবেন ।

    [[NSUserDefaults standardUserDefaults] setValue:value forKey:key]
    [[NSUserDefaults standardUserDefaults] objectForKey:key]
  2. আপনি কেবল এখানে একটি সম্পত্তি তৈরি করতে পারেন viewcontrollerAviewcontrollerAইন অবজেক্ট তৈরি করুন viewcontrollerBএবং সেই সম্পত্তিটিতে পছন্দসই মান নির্ধারণ করুন।

  3. আপনি এর জন্য কাস্টম প্রতিনিধিও তৈরি করতে পারেন।


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

30

আপনি যদি কোনও নিয়ামক থেকে অন্যটিতে ডেটা পাস করতে চান তবে এই কোডটি ব্যবহার করে দেখুন

FirstViewController.h

@property (nonatomic, retain) NSString *str;

SecondViewController.h

@property (nonatomic, retain) NSString *str1;

FirstViewController.m

- (void)viewDidLoad
   {
     // message for the second SecondViewController
     self.str = @"text message";

     [super viewDidLoad];
   }

-(IBAction)ButtonClicked
 {
   SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
   secondViewController.str1 = str;
  [self.navigationController pushViewController:secondViewController animated:YES];
 }

29

এটি একটি খুব পুরানো উত্তর এবং এটি বিরোধী নিদর্শন, দয়া করে প্রতিনিধিদের ব্যবহার করুন। এই পদ্ধতির ব্যবহার করবেন না !!

1. দ্বিতীয় ভিউ কন্ট্রোলারে প্রথম ভিউ কন্ট্রোলারের উদাহরণ তৈরি করুন এবং এর সম্পত্তি তৈরি করুন @property (nonatomic,assign)

২.SecondviewController এই ভিউ কন্ট্রোলারের উদাহরণটি বরাদ্দ করুন ।

২. আপনি যখন নির্বাচন অপারেশন শেষ করেন অ্যারেটিকে প্রথম দেখার নিয়ন্ত্রকের কাছে অনুলিপি করুন, আপনি যখন দ্বিতীয় ভিউটি আনলোড করবেন তখন ফার্স্টভিউ অ্যারের ডেটা ধরে রাখবে।

আশাকরি এটা সাহায্য করবে.


2
আমি এটি বিশ্বাস করি না যে এটি যাওয়ার সঠিক উপায় কারণ এটি দেখুন নিয়ন্ত্রণকারীদের মধ্যে খুব রেঞ্জযুক্ত লিঙ্ক তৈরি করে। সত্যিই এমভিসির সাথে লেগে থাকা নয়।
ম্যাট দাম

1
আপনি কঠোরভাবে MVC অনুসরণ করতে চান করেন, ব্যবহার NSNotificationCenter একটি পদ্ধতি ViewControllerB করার ViewControllerA থেকে বলা যেতে পারে, চেক এই এটা তোমার দর্শন লগ করা সাহায্য করতে পারে
kaar3k

28

আমি দীর্ঘদিন ধরে এই সমাধানটি অনুসন্ধান করছিলাম, আটলাস্ট আমি এটি খুঁজে পেয়েছি। সবার আগে আপনার দ্বিতীয় ভিউকন্ট্রোল.আর ফাইলের মতো সমস্ত বস্তু ঘোষণা করুন

@interface SecondViewController: UIviewController 
{
    NSMutableArray *myAray;
    CustomObject *object;
}

এখন আপনার বাস্তবায়নের ফাইলটিতে এই জাতীয় বস্তুর জন্য মেমরি বরাদ্দ করুন

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
     if (self) 
     {
         // Custom initialization
         myAray=[[NSMutableArray alloc] init];
         object=[[CustomObject alloc] init];
     }
     return self;
}

এখন আপনি মেমরি বরাদ্দ করেছেন Arrayএবং আপত্তি করুন। এখন আপনি এটিকে চাপ দেওয়ার আগে সেই স্মৃতিটি পূরণ করতে পারেনViewController

আপনার সেকেন্ডভিউকন্ট্রোল.আর যান এবং দুটি পদ্ধতি লিখুন

-(void)setMyArray:(NSArray *)_myArray;
-(void)setMyObject:(CustomObject *)_myObject;

বাস্তবায়ন ফাইল আপনি ফাংশন বাস্তবায়ন করতে পারেন

-(void)setMyArray:(NSArray *)_myArray
{
     [myArra addObjectsFromArray:_myArray];
}
-(void)setMyObject:(CustomObject *)_myObject
{
     [object setCustomObject:_myObject];
}

আপনার CustomObjectঅবশ্যই এটির সাথে একটি সেটার ফাংশন থাকতে হবে আশা করে।

এখন আপনার বেসিক কাজ শেষ। আপনি যে জায়গায় চাপ দিতে চান সেখানে যান SecondViewControllerএবং নীচের জিনিসগুলি করুন

SecondViewController *secondView= [[SecondViewController alloc] initWithNibName:@"SecondViewController " bundle:[NSBundle MainBundle]] ;
[secondView setMyArray:ArrayToPass];
[secondView setMyObject:objectToPass];
[self.navigationController pushViewController:secondView animated:YES ];

বানান ভুলের জন্য যত্ন নিন।


24

এটি করার উপায় এটি নয়, আপনার প্রতিনিধিদের ব্যবহার করা উচিত, আমি ধরে নেব যে আমাদের কাছে দুটি ভিউ কন্ট্রোলার ভিউ কন্ট্রোলার 1 এবং ভিউকন্ট্রোলার 2 রয়েছে এবং এই চেক জিনিসটি প্রথমটির মধ্যে রয়েছে এবং যখন এর রাজ্য পরিবর্তন হয়, আপনি ভিউকন্ট্রোলার 2 তে কিছু করতে চান, এটি সঠিক উপায়ে অর্জন করুন, আপনার নীচের কাজটি করা উচিত:

আপনার প্রকল্পে একটি নতুন ফাইল যুক্ত করুন (অবজেক্টিভ-সি প্রোটোকল) ফাইল -> নতুন, এখন এটির নাম দেখুন ViewController1Delegate বা যা আপনি চান এবং এগুলি লিখুন @ আন্তঃআরক্ষেত্র এবং @ শেষ নির্দেশের মধ্যে

@optional

- (void)checkStateDidChange:(BOOL)checked;

এখন ViewController2.h এ যান এবং যুক্ত করুন

#import "ViewController1Delegate.h"

তারপরে এর সংজ্ঞাটি পরিবর্তন করুন

@interface ViewController2: UIViewController<ViewController1Delegate>

এখন ViewController2.m এ যান এবং প্রয়োগের অভ্যন্তরে যোগ করুন:

- (void)checkStateDidChange:(BOOL)checked {
     if (checked) {
           // Do whatever you want here
           NSLog(@"Checked");
     }
     else {
           // Also do whatever you want here
           NSLog(@"Not checked");
     }
}

এখন ViewController1.h এ যান এবং নিম্নলিখিত সম্পত্তি যুক্ত করুন:

@property (weak, nonatomic) id<ViewController1Delegate> delegate; 

এখন আপনি যদি কোনও ইভেন্টের পরে ভিউকন্ট্রোলার 2 এর মধ্যে ভিউকন্ট্রোলার 1 তৈরি করে থাকেন তবে আপনার NIB ফাইলগুলি ব্যবহার করে এটি করা উচিত:

ViewController1* controller = [[NSBundle mainBundle] loadNibNamed:@"ViewController1" owner:self options:nil][0];
controller.delegate = self;
[self presentViewController:controller animated:YES completion:nil];

এখন আপনি সম্পূর্ণ প্রস্তুত, যখনই আপনি ভিউকন্ট্রোলার 1-এ পরিবর্তিত চেকের ইভেন্টটি সনাক্ত করেন, আপনাকে যা করতে হবে তা নীচে

[delegate checkStateDidChange:checked]; // You pass here YES or NO based on the check state of your control

আমি যদি আপনার প্রশ্নটি সঠিকভাবে বুঝতে না পারি তবে এমন কিছু আছে যা সম্পর্কে পরিষ্কার নয় দয়া করে আমাকে বলুন।


23

যদি আপনি এক থেকে অন্য ভিউ কন্ট্রোলারের কাছে ডেটা প্রেরণ করতে চান তবে এখানে এটির জন্য একটি উপায়:

বলুন আমাদের কাছে ভিউকন্ট্রোলার রয়েছে: ভিউকন্ট্রোলারএ এবং ভিউ কন্ট্রোলারবি

এখন ভিউকন্ট্রোলারবি

@interface viewControllerB : UIViewController {

  NSString *string;
  NSArray *array;

}

- (id)initWithArray:(NSArray)a andString:(NSString)s;

ভিউকন্ট্রোলারবি.এম.

#import "viewControllerB.h"

@implementation viewControllerB

- (id)initWithArray:(NSArray)a andString:(NSString)s {

   array = [[NSArray alloc] init];
   array = a;

   string = [[NSString alloc] init];
   string = s;

}

ভিউকন্ট্রোলারএ.এম তে

#import "viewControllerA.h"
#import "viewControllerB.h"

@implementation viewControllerA

- (void)someMethod {

  someArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
  someString = [NSString stringWithFormat:@"Hahahahaha"];

  viewControllerB *vc = [[viewControllerB alloc] initWithArray:someArray andString:someString];

  [self.navigationController pushViewController:vc animated:YES];
  [vc release];

}

সুতরাং আপনি কোনও প্রতিনিধি সেট না করেই ভিউ কন্ট্রোলারএ থেকে ভিউ কন্ট্রোলারবিতে ডেটা পাস করতে পারেন। ;)


1
আমি আমার প্রকল্পে আপনার কোডটি ব্যবহার করার চেষ্টা করেছি, তবে ভিউকন্ট্রোলারবিতে মানগুলি অর্জন করতে পারছি না। আপনি কি বলতে পারেন সমস্যাটি কি হতে পারে?
এক্স কোডার

1
@ অজিথালা আপনি কি একটি নতুন প্রশ্নে আপনার কোড পেস্ট করতে পারেন? আমি আপনার সমস্যা সমাধান করার চেষ্টা করব। :)
অনিরুদ্ধ জোশী

1
থিম পদ্ধতিগুলি ব্যবহার না করা, এবং ভিউকন্ট্রোলার এ থেকে কেবল ভিসিবি.স্ট্রিং = @ "এসএসডিএফ" এর মতো কিছু করা কি ভুল?
khanh.tran.vinh

1
@ khanh.tran.vinh আপনি ARC ব্যবহার করছেন কিনা তা নির্ভর করে।
অনিরুদ্ধ জোশী

21

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

এটি উপরের মতো তবে বোতাম, লেবেল এবং এগুলি ছাড়া। কেবল একটি ভিউ থেকে পরের বারে ডেটা পাস করা।

স্টোরিবোর্ড সেটআপ করুন

তিনটি অংশ আছে।

  1. প্রেরক
  2. দ্য সেগ
  3. গ্রাহক

এটি তাদের মধ্যে মধ্যবর্তী অংশ নিয়ে একটি খুব সহজ ভিউ লেআউট।


খুব সাধারণ ভিউ বিন্যাস।  দ্রষ্টব্য: কোনও নেভিগেশন নিয়ামক নেই


এখানে প্রেরকের জন্য সেটআপ রয়েছে


প্রেরক


এখানে রিসিভারের জন্য সেটআপ রয়েছে।


গ্রাহক


সবশেষে, সিগের জন্য সেটআপ।


সিগু আইডেন্টিফায়ার


দ্য কন্ট্রোলাররা

আমরা এটিকে এত সহজ রাখছি যাতে কোনও বোতাম নয়, ক্রিয়া নয়, আমরা অ্যাপ্লিকেশনটি লোড করার পরে প্রেরক থেকে ডেটা প্রাপক থেকে সরানো হয় এবং তারপরে কনসোলে স্থানান্তরিত মান আউটপুট করে চলেছি।

এই পৃষ্ঠাটি প্রাথমিকভাবে লোড হওয়া মান নেয় এবং এটি পাশ করে দেয়।

import UIKit


class ViewControllerSender: UIViewController {

    // THE STUFF - put some info into a variable
    let favoriteMovie = "Ghost Busters"

    override func viewDidAppear(animated: Bool) {
        // PASS IDENTIFIER - go to the recieving view controller.
        self.performSegueWithIdentifier("goToReciever", sender: self)
    }

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

        //GET REFERENCE - ...to the receiver view.
        var viewControllerReceiver = segue.destinationViewController as? ViewControllerReceiver

        //PASS STUFF - pass the variable along to the target.
        viewControllerReceiver!.yourFavMovie = self.favoriteMovie

    }

}

এই পৃষ্ঠাটি ভেরিয়েবলের মানটি কনসোলে প্রেরণ করে যখন এটি লোড হয়। এই মুহুর্তে, আমাদের প্রিয় সিনেমাটি সেই পরিবর্তনশীল হওয়া উচিত।

import UIKit

class ViewControllerReceiver: UIViewController {

    //Basic empty variable waiting for you to pass in your fantastic favorite movie.
    var yourFavMovie = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        //And now we can view it in the console.
        println("The Movie is \(self.yourFavMovie)")

    }   
}

আপনি যদি কোনও সিগু ব্যবহার করতে চান এবং আপনার পৃষ্ঠাগুলি নেভিগেশন নিয়ামকের অধীনে না থাকে আপনি কীভাবে এটি মোকাবেলা করতে পারবেন।

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

ঘোস্ট বুস্টার্স একটি ক্লাসিক ভাবেন।


19

আমার ক্ষেত্রে আমি একটি সিঙ্গলটন ক্লাস ব্যবহার করেছি যা অ্যাপ্লিকেশনটিতে প্রায় সর্বত্র থেকে ডেটা অ্যাক্সেসের অনুমতি দেওয়ার জন্য একটি বিশ্বব্যাপী অবজেক্ট হিসাবে কাজ করতে পারে। প্রথম জিনিসটি একটি সিঙ্গলটন ক্লাস তৈরি করা। দয়া করে পৃষ্ঠাটি দেখুন, " আমার অবজেক্টিভ সি সিঙ্গলটন দেখতে কেমন হবে? " এবং বিশ্বব্যাপী অ্যাক্সেসযোগ্য করার জন্য আমি যা করেছি তা কেবল এটি আমদানি করা হয়েছিল appName_Prefix.pchযাতে প্রতিটি ক্লাসে আমদানি বিবৃতি প্রয়োগ করার জন্য। এই অবজেক্টটি অ্যাক্সেস করতে এবং ব্যবহার করতে, আমি ভাগ করে নেওয়া দৃষ্টান্তটি ফিরিয়ে দিতে ক্লাস পদ্ধতিটি সহজভাবে প্রয়োগ করেছি, যার নিজস্ব ভেরিয়েবল রয়েছে


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

1
তবে দ্রষ্টব্য যে এই দিনগুলিতে (2016+) "সবকিছুই আইওএস-এ একটি ধারক দর্শন"। আপনি স্ক্রিনে প্রতিটি একক জিনিস আপনি কিছুটা ধারক দেখান। কনটেইনার ভিউগুলির "আপ এবং ডাউন" চেইনগুলি পাওয়া মোটামুটি নগণ্য (যদিও অ্যাপল ভবিষ্যতে এটি আরও সহজ করে তুলবে), এবং আপনি যাইহোক প্রায় প্রতিটি কন্টেইনার দর্শনের জন্য এটি করেন। সুতরাং, যদি আপনি যাইহোক এটি করেন - আপনার উত্তর আছে; সিঙ্গলটনের দরকার নেই। ধারক দেখার ভূমিকা ... স্ট্যাকওভারফ্লো
23403979/

19

সুইফট 5

ওয়েল ম্যাট প্রাইসের উত্তর ডেটা পাস করার জন্য পুরোপুরি ঠিক আছে তবে আমি এটি নতুন করে লিখতে চলেছি, সর্বশেষ সুইফ্ট সংস্করণে কারণ আমি বিশ্বাস করি যে নতুন প্রোগ্রামাররা এটি নতুন সিনট্যাক্স এবং পদ্ধতি / কাঠামোর কারণে চ্যালেঞ্জিং ছেড়ে দিয়েছে বলে মূল পোস্টটি উদ্দেশ্য সি-তে রয়েছে।

ভিউ কন্ট্রোলারের মধ্যে ডেটা পাস করার জন্য একাধিক বিকল্প রয়েছে।

  1. নেভিগেশন কন্ট্রোলার পুশ ব্যবহার করা
  2. Segue ব্যবহার
  3. প্রতিনিধি ব্যবহার
  4. বিজ্ঞপ্তি পর্যবেক্ষক ব্যবহার করে
  5. ব্লক ব্যবহার করা হচ্ছে

আমি সর্বশেষ আইওএস ফ্রেমওয়ার্ক সহ সুইফটে তার যুক্তিটি আবার লিখতে চলেছি


নেভিগেশন কন্ট্রোলার পুশ হয়ে ডেটা পাসিং : ভিউকন্ট্রোলারএ থেকে ভিউকন্ট্রোলারবিতে

পদক্ষেপ 1. ViewControllerB এ পরিবর্তনীয় ঘোষণা করুন Dec

var isSomethingEnabled = false

পদক্ষেপ 2. ViewControllerB এর ViewDidLoad পদ্ধতিতে পরিবর্তনীয় মুদ্রণ করুন

override func viewDidLoad() {
        super.viewDidLoad()
        //Print value received through segue, navigation push
        print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
    }

পদক্ষেপ 3. নেভিগেশন কন্ট্রোলারের মাধ্যমে ধাক্কা দেওয়ার সময় ভিউকন্ট্রোলারএ পাস ডেটা

if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
        viewControllerB.isSomethingEnabled = true
        if let navigator = navigationController {
            navigator.pushViewController(viewControllerB, animated: true)
        }
    }

সুতরাং এখানে সম্পূর্ণ কোড এখানে:

ViewControllerA

import UIKit

class ViewControllerA: UIViewController  {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK:Passing Data through Navigation PushViewController
    @IBAction func goToViewControllerB(_ sender: Any) {

        if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
            viewControllerB.isSomethingEnabled = true
            if let navigator = navigationController {
                navigator.pushViewController(viewControllerB, animated: true)
            }
        }
    }
}

ViewControllerB

import UIKit

class ViewControllerB: UIViewController {

    //MARK:  - Variable for Passing Data through Navigation push   
    var isSomethingEnabled = false

    override func viewDidLoad() {
        super.viewDidLoad()
        //Print value received through navigation push
        print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
    }
}

সেগুর মাধ্যমে ডেটা পাসিং : ভিউকন্ট্রোলারএ থেকে ভিউকন্ট্রোলারবিতে

পদক্ষেপ 1. ভিউ কন্ট্রোলারএ থেকে ভিউকন্ট্রোলারবিতে সেগু তৈরি করুন এবং স্টোরিবোর্ডে আইডেন্টিফায়ার = শোডেটেলসইগু নিন

এখানে চিত্র বর্ণনা লিখুন

পদক্ষেপ ২. ভিউকন্ট্রোলারবিতে একটি সার্থক নামসোমথিংএনেবলড ঘোষণা করুন এবং এর মানটি মুদ্রণ করুন।

পদক্ষেপ ৩. ভিউকন্ট্রোলার পাসে সিগু উত্তীর্ণ হওয়ার সময়সামথিংএনেবলের মান

সুতরাং এখানে সম্পূর্ণ কোড এখানে:

ViewControllerA

import UIKit

class ViewControllerA: UIViewController  {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK:  - - Passing Data through Segue  - - 
    @IBAction func goToViewControllerBUsingSegue(_ sender: Any) {
        performSegue(withIdentifier: "showDetailSegue", sender: nil)
    }

    //Segue Delegate Method
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "showDetailSegue") {
            let controller = segue.destination as? ViewControllerB
            controller?.isSomethingEnabled = true//passing data
        }
    }
}

ViewControllerB

import UIKit

class ViewControllerB: UIViewController {
    var isSomethingEnabled = false

    override func viewDidLoad() {
        super.viewDidLoad()
        //Print value received through segue
        print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
    }
}

প্রতিনিধিটির মাধ্যমে ডেটা পাস করা : ভিউকন্ট্রোলারবি থেকে ভিউকন্ট্রোলারএ

পদক্ষেপ 1. প্রোটোকল ভিউ কন্ট্রোলার বি ডেলিগেট ঘোষণা ভিকন্ট্রোলারবি ফাইলে কিন্তু শ্রেণীর বাইরে

protocol ViewControllerBDelegate: NSObjectProtocol {

    // Classes that adopt this protocol MUST define
    // this method -- and hopefully do something in
    // that definition.
    func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}

পদক্ষেপ 2. ViewControllerB এ ডেলিগেট ভেরিয়েবল উদাহরণ ঘোষণা করুন

var delegate: ViewControllerBDelegate?

পদক্ষেপ 3. ভিউকন্ট্রোলারবি'র ভিডিডিলোড পদ্ধতিতে ডেলিগেটের জন্য ডেটা প্রেরণ করুন

delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")

পদক্ষেপ 4. ভিউকন্ট্রোলারএতে ViewControllerBDelegate নিশ্চিত করুন

class ViewControllerA: UIViewController, ViewControllerBDelegate  {
// to do
}

পদক্ষেপ 5. নিশ্চিত করুন যে আপনি ভিউকন্ট্রোলারএতে প্রতিনিধি প্রয়োগ করবেন

if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
            viewControllerB.delegate = self//confirming delegate
            if let navigator = navigationController {
                navigator.pushViewController(viewControllerB, animated: true)
            }
        }

পদক্ষেপ View. ভিউকন্ট্রোলারএতে ডেটা পাওয়ার জন্য ডেলিগেট পদ্ধতিটি প্রয়োগ করুন

func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
        print("Value from ViewControllerB's Delegate", item!)
    }

সুতরাং এখানে সম্পূর্ণ কোড এখানে:

ViewControllerA

import UIKit

class ViewControllerA: UIViewController, ViewControllerBDelegate  {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //Delegate method
    func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
        print("Value from ViewControllerB's Delegate", item!)
    }

    @IBAction func goToViewControllerForDelegate(_ sender: Any) {

        if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
            viewControllerB.delegate = self
            if let navigator = navigationController {
                navigator.pushViewController(viewControllerB, animated: true)
            }
        }
    }
}

ViewControllerB

import UIKit

//Protocol decleare
protocol ViewControllerBDelegate: NSObjectProtocol {
    // Classes that adopt this protocol MUST define
    // this method -- and hopefully do something in
    // that definition.
    func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}

class ViewControllerB: UIViewController {
    var delegate: ViewControllerBDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        //MARK:  - - - -  Set Data for Passing Data through Delegate  - - - - - -
        delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
    }
}

বিজ্ঞপ্তি পর্যবেক্ষকের মাধ্যমে ডেটা পাস করা : ভিউকন্ট্রোলারবি থেকে ভিউকন্ট্রোলারএ

পদক্ষেপ 1. ভিউকন্ট্রোলারবিতে বিজ্ঞপ্তি পর্যবেক্ষকগুলিতে ডেটা সেট এবং পোস্ট করুন

let objToBeSent = "Test Message from Notification"
        NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)

পদক্ষেপ 2. ভিউকন্ট্রোলারএতে বিজ্ঞপ্তি পর্যবেক্ষক যুক্ত করুন

NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

পদক্ষেপ 3. ViewControllerA এ বিজ্ঞপ্তি ডেটা মান পান Re

@objc func methodOfReceivedNotification(notification: Notification) {
        print("Value of notification : ", notification.object ?? "")
    }

সুতরাং এখানে সম্পূর্ণ কোড এখানে:

ViewControllerA

import UIKit

class ViewControllerA: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()

        // add observer in controller(s) where you want to receive data
        NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
    }

    //MARK: Method for receiving Data through Post Notification 
    @objc func methodOfReceivedNotification(notification: Notification) {
        print("Value of notification : ", notification.object ?? "")
    }
}

ViewControllerB

import UIKit

class ViewControllerB: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //MARK:Set data for Passing Data through Post Notification
        let objToBeSent = "Test Message from Notification"
        NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
    }
}

ব্লক হয়ে ডেটা পাসিং : ভিউকন্ট্রোলারবি থেকে ভিউকন্ট্রোলারএ

পদক্ষেপ 1. ViewControllerB এ ব্লক ঘোষণা করুন

var অনুমোদন কমপ্লিটব্লক: ((বুল) -> ())? = {_ ইন}

পদক্ষেপ 2. ভিউকন্ট্রোলারবি ব্লকে ডেটা সেট করুন

if authorizationCompletionBlock != nil
        {
            authorizationCompletionBlock!(true)
        }

পদক্ষেপ 3. ViewControllerA এ ব্লক ডেটা গ্রহণ করুন

//Receiver Block
                controller!.authorizationCompletionBlock = { isGranted in
                    print("Data received from Block is :", isGranted)
                }

সুতরাং এখানে সম্পূর্ণ কোড এখানে:

ViewControllerA

import UIKit

class ViewControllerA: UIViewController  {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK:Method for receiving Data through Block
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if (segue.identifier == "showDetailSegue") {
                let controller = segue.destination as? ViewControllerB
                controller?.isSomethingEnabled = true

                //Receiver Block
                controller!.authorizationCompletionBlock = { isGranted in
                    print("Data received from Block is :", isGranted)
                }
            }
        }
}

ViewControllerB

import UIKit

class ViewControllerB: UIViewController {

    //MARK:Variable for Passing Data through Block
    var authorizationCompletionBlock:((Bool)->())? = {_ in}

    override func viewDidLoad() {
        super.viewDidLoad()

        //MARK:Set data for Passing Data through Block
        if authorizationCompletionBlock != nil
        {
            authorizationCompletionBlock!(true)
        }
    }
}

আপনি আমার গিটহাব এ সম্পূর্ণ নমুনা অ্যাপ্লিকেশনটি পেতে পারেন দয়া করে এ সম্পর্কে আপনার কোনও প্রশ্ন (গুলি) রয়েছে কিনা তা আমাকে জানান।


18

নিচের মত দ্বিতীয় ভিউকন্ট্রোলারের কাছে ফার্স্টভিউ কনট্রোলারের মধ্যে ডেটা পাস করা

উদাহরণ স্বরূপ:

ফার্স্টভিউকন্ট্রোলার স্ট্রিংয়ের মান হিসাবে

StrFirstValue = @"first";

সুতরাং আমরা নীচের পদক্ষেপটি ব্যবহার করে দ্বিতীয় শ্রেণিতে এই মানটি পাস করতে পারি

1> আমাদের দ্বিতীয় ভিউকন্ট্রোল.আর ফাইলটিতে স্ট্রিং অবজেক্টের ক্রেট করা দরকার

NSString *strValue;

2> নীচের হিসাবে .h ফাইলে ঘোষণা হিসাবে সম্পত্তি ঘোষণা করা দরকার

@property (strong, nonatomic)  NSString *strSecondValue;

3> শিরোনাম ঘোষণার নীচে ফার্স্টভিউকন্ট্রোলআরমি ফাইলটিতে সেই মানটি সংশ্লেষ করা দরকার

@synthesize strValue;

এবং ফার্স্টভিউ কন্ট্রোল.আরে:

@property (strong, nonatomic)  NSString *strValue;

4> ফার্স্টভিউ নিয়ন্ত্রণকারীতে, কোন পদ্ধতি থেকে আমরা দ্বিতীয় দৃষ্টিতে নেভিগেট করি সেই পদ্ধতিতে কোডের নীচে লিখুন।

SecondViewController *secondView= [[SecondViewController alloc]     
initWithNibName:@"SecondViewController " bundle:[NSBundle MainBundle]];

[secondView setStrSecondValue:StrFirstValue];

[self.navigationController pushViewController:secondView animated:YES ];

সেকেন্ডভিউ কনট্রোলারে থাকার পরে আপনি কীভাবে ডেটা फर्জভিউ নিয়ন্ত্রণকারীকে ফেরত দেবেন?
ব্রুনো

18

আমি বর্তমানে এমসিভিউফ্যাক্টরি নামে একটি প্রকল্পের মাধ্যমে এই সমস্যার ওপেন সোর্স সমাধানে অবদান রাখছি, যা এখানে পাওয়া যেতে পারে:

https://github.com/YetiHQ/manticore-iosviewfactory

ধারণাটি হ'ল অ্যান্ড্রয়েডের অভিপ্রায়ের দৃষ্টান্তটি অনুকরণ করে আপনি কোন দর্শনটি দেখছেন তা পরিচালনা করার জন্য একটি বিশ্ব কারখানা ব্যবহার করে এবং ভিউগুলির মধ্যে ডেটা স্যুইচ এবং পাস করার জন্য "অভিপ্রায়" ব্যবহার করে। সমস্ত ডকুমেন্টেশনগুলি গিথুব পৃষ্ঠায় রয়েছে তবে এখানে কয়েকটি হাইলাইট রয়েছে:

আপনি কারখানাটি সূচনা করার সময় আপনার সমস্ত দর্শন .XIB ফাইলগুলিতে সেটআপ করেন এবং অ্যাপ প্রতিনিধিতে তাদের নিবন্ধভুক্ত করেন।

// Register activities

MCViewFactory *factory = [MCViewFactory sharedFactory];

// the following two lines are optional. 
[factory registerView:@"YourSectionViewController"]; 

এখন, আপনার ভিসিতে, যে কোনও সময় আপনি কোনও নতুন ভিসিতে যেতে চান এবং ডেটা পাস করতে চান, আপনি একটি নতুন অভিপ্রায় তৈরি করেন এবং এর অভিধানে (সেভড ইনস্ট্যান্সস্টেট) ডেটা যুক্ত করেন। তারপরে, কেবল কারখানার বর্তমান অভিপ্রায় সেট করুন:

MCIntent* intent = [MCIntent intentWithSectionName:@"YourSectionViewController"];
[intent setAnimationStyle:UIViewAnimationOptionTransitionFlipFromLeft];
[[intent savedInstanceState] setObject:@"someValue" forKey:@"yourKey"];
[[intent savedInstanceState] setObject:@"anotherValue" forKey:@"anotherKey"];
// ...
[[MCViewModel sharedModel] setCurrentSection:intent];

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

-(void)onResume:(MCIntent *)intent {
    NSObject* someValue = [intent.savedInstanceState objectForKey:@"yourKey"];
    NSObject* anotherValue = [intent.savedInstanceState objectForKey:@"anotherKey"];

    // ...

    // ensure the following line is called, especially for MCSectionViewController
    [super onResume:intent];
}

আশা করি আপনারা কেউ কেউ এই সমাধানটিকে দরকারী / আকর্ষণীয় বলে মনে করেন।


তারপরে সমস্ত কন্ট্রোলার অবজেক্টগুলি কোনও স্কোপে সমস্ত নিবন্ধিত অভিধান পেতে / সেট করতে পারে? এটিকে কমিয়ে দিন।
ইটাচি

15

পরের দিকে সম্পত্তি তৈরি করুন view controller .hএবং গেটর এবং সেটার সংজ্ঞায়িত করুন।

এটিকে propertyনেক্সটভিসিতে NextVC.h এ যুক্ত করুন

@property (strong, nonatomic) NSString *indexNumber;

যোগ

@synthesize indexNumber; NextVC.m এ

এবং অবশেষে

NextVC *vc=[[NextVC alloc]init];

vc.indexNumber=@"123";

[self.navigationController vc animated:YES];

11

এটি করার অনেকগুলি উপায় রয়েছে এবং সঠিকটি চয়ন করা গুরুত্বপূর্ণ। মডেল কোডটি কীভাবে অ্যাপ্লিকেশন জুড়ে ভাগ করা বা অ্যাক্সেস করা হবে তার উপর সম্ভবত সবচেয়ে বড় একটি স্থাপত্য সিদ্ধান্ত decisions

আমি এই সম্পর্কে কিছুক্ষণ আগে একটি ব্লগ পোস্ট লিখেছিলাম: মডেল কোডটি ভাগ করে নেওয়া । এখানে একটি সংক্ষিপ্তসার:

ভাগ করা ডেটা

একটি পন্থা হল ভিউ কন্ট্রোলারের মধ্যে মডেল অবজেক্টগুলিতে পয়েন্টার ভাগ করে নেওয়া।

  • ডেটা সেট করতে ভিউ কন্ট্রোলারগুলিতে (নেভিগেশন বা ট্যাব বার কন্ট্রোলারে) ব্রুট ফোর্স পুনরুক্তি
  • রেডিফোরসেগ্রে ডেটা সেট করুন (স্টোরিবোর্ডগুলি থাকলে) বা আরআইডি (প্রোগ্রামিং যদি থাকে)

যেহেতু সেগের জন্য প্রস্তুতি সর্বাধিক সাধারণ এখানে একটি উদাহরণ:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var next = segue.destinationViewController as NextViewController
    next.dataSource = dataSource
}

স্বতন্ত্র প্রবেশাধিকার

আরেকটি পদ্ধতি হ'ল একবারে ডেটা পূর্ণ স্ক্রিন পরিচালনা করা এবং ভিউ কন্ট্রোলারগুলিকে একে অপরের সাথে সংযুক্ত করার পরিবর্তে প্রতিটি ভিউ নিয়ামককে একক ডেটা উত্সের সাথে সংযুক্ত করা যা তারা স্বতন্ত্রভাবে পেতে পারে।

সর্বাধিক সাধারণভাবে আমি এই কাজটি দেখেছি এটি হ'ল একক উদাহরণ। সুতরাং যদি আপনার সিঙ্গলটন অবজেক্টটি DataAccessআপনি ইউআইভিউকন্ট্রোলারের ভিউডিডলড পদ্ধতিতে নিম্নলিখিতগুলি করতে পারতেন:

func viewDidLoad() {
    super.viewDidLoad()
    var data = dataAccess.requestData()
}

এছাড়াও অতিরিক্ত সরঞ্জাম রয়েছে যা ডেটা বরাবরও সহায়তা করে:

  • কী-মান পর্যবেক্ষণ
  • NSNotification
  • মূল তথ্য
  • NSFetchedResultsController
  • তথ্য সূত্র

মূল তথ্য

কোর ডেটা সম্পর্কে দুর্দান্ত জিনিসটি হ'ল এর বিপরীত সম্পর্ক রয়েছে। সুতরাং আপনি যদি একটি নোটভিউ কনট্রোলারকে কেবলমাত্র নোটগুলি দিতে পারেন তবে আপনি নোটবুকের মতো অন্য কোনও জিনিসের সাথে বিপরীত সম্পর্ক রাখতে পারেন give নোটস ভিউ কনট্রোলারের নোটবুকে যদি আপনার ডেটা প্রয়োজন হয় তবে আপনি নীচের কাজ করে অবজেক্ট গ্রাফটি ব্যাক আপ করতে পারবেন:

let notebookName = note.notebook.name

আমার ব্লগ পোস্টে এ সম্পর্কে আরও পড়ুন: শেয়ারিং মডেল কোড


10

NewsViewController

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  [tbl_View deselectRowAtIndexPath:indexPath animated:YES];
  News *newsObj = [newstitleArr objectAtIndex:indexPath.row];
  NewsDetailViewController *newsDetailView = [[NewsDetailViewController alloc] initWithNibName:@"NewsDetailViewController" bundle:nil];

  newsDetailView.newsHeadlineStr = newsObj.newsHeadline;

  [self.navigationController pushViewController:newsDetailView animated:YES];
}

NewsDetailViewController.h

@interface NewsDetailViewController : UIViewController
@property(nonatomic,retain) NSString *newsHeadlineStr;
@end

NewsDetailViewController.m

@synthesize newsHeadlineStr;

10

আপনি .xib ফাইল ব্যবহার করার সময় ডেলিগেশন হ'ল একমাত্র সমাধান তবে উপরে বর্ণিত সমস্ত উত্তরগুলি storyboard.xib ফাইলগুলির জন্য আপনার প্রতিনিধিদলটি ব্যবহার করা দরকার। এটিই কেবল আপনি সমাধান করতে পারেন।

আরেকটি সমাধান হ'ল সিঙ্গলটন ক্লাসের প্যাটার্নটি একবারে এটি আরম্ভ করুন এবং এটি আপনার সম্পূর্ণ অ্যাপ্লিকেশনটিতে ব্যবহার করুন।


10

যদি আপনি ভিউ কন্ট্রোলারও থেকে ডেটা ভিউকন্ট্রোলারতে পাস করতে চান তবে এই চেষ্টা করুন ..

এগুলি ভিউকন্ট্রোলারওনে করুন in

 @property (nonatomic, strong) NSString *str1;

এগুলিকে ভিউকন্ট্রোলার টু

 @property (nonatomic, strong) NSString *str2;

ViewControllerTwo.m এ আর্ট 2 সংশ্লেষিত করুন

@interface ViewControllerTwo ()
@end
@implementation ViewControllerTwo
@synthesize str2;

এগুলি ভিউকন্ট্রোলারঅনে.এম. এ করুন

 - (void)viewDidLoad
 {
   [super viewDidLoad];

  // Data or string you wants to pass in ViewControllerTwo..
  self.str1 = @"hello world";

 }

বাটনে ক্লিক ইভেন্ট ক্লিক করুন ..

-(IBAction)ButtonClicked
{ //Navigation on buttons click event from ViewControlerOne to ViewControlerTwo with transferring data or string..
  ViewControllerTwo *objViewTwo=[self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerTwo"];
  obj.str2=str1;
  [self.navigationController pushViewController: objViewTwo animated:YES];
}

এগুলি ভিউকন্ট্রোলারটু.এম. এ করুন

- (void)viewDidLoad
{
 [super viewDidLoad];
  NSLog(@"%@",str2);
}

10

আপনার অ্যাপ্লিকেশনটিতে দৃশ্য নিয়ন্ত্রণকারীদের জুড়ে এটি অ্যাক্সেসের জন্য আপনি অ্যাপের প্রতিনিধিতে ডেটা সংরক্ষণ করতে পারেন। আপনাকে যা করতে হবে তা হ'ল অ্যাপ প্রতিনিধিদের একটি ভাগ করা ইভেন্ট তৈরি করা

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

উদাহরণ স্বরূপ

যদি আপনি কোনও ঘোষণা করেন NSArray object *arrayXYZতবে আপনি এটিকে কোনও ভিউ কন্ট্রোলারে অ্যাক্সেস করতে পারবেনappDelegate.arrayXYZ


এটি হ্যাকাথনের পছন্দের পদ্ধতি
হাই ফেং কাও

9

যদি আপনি এক থেকে অন্য ভিউ কন্ট্রোলারের কাছে ডেটা প্রেরণ করতে চান তবে এখানে এটির জন্য একটি উপায়:

বলুন আমাদের কাছে ভিউকন্ট্রোলার রয়েছে: ভিউকন্ট্রোলার এবং নিউভিউ কন্ট্রোলার।

ViewController.h এ

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    IBOutlet UITextField *mytext1,*mytext2,*mytext3,*mytext4;
}

@property (nonatomic,retain) IBOutlet UITextField *mytext1,*mytext2,*mytext3,*mytext4;

-(IBAction)goToNextScreen:(id)sender;

@end

ViewController.m এ

#import "ViewController.h"

#import "NewViewController.h"

@implementation ViewController
@synthesize mytext1,mytext2,mytext3,mytext4;

-(IBAction)goToNextScreen:(id)sender
{
    NSArray *arr = [NSArray arrayWithObjects:mytext1.text,mytext2.text,mytext3.text,mytext4.text, nil];


    NewViewController *newVc = [[NewViewController alloc] initWithNibName:@"NewViewController" bundle:nil];

    newVc.arrayList = arr;

    [self.navigationController pushViewController:newVc animated:YES];

}

নিউভিউকন্ট্রোল.আরে

#import <UIKit/UIKit.h>

@interface NewViewController : UITableViewController
{
    NSArray *arrayList;

    NSString *name,*age,*dob,*mobile;

}

@property(nonatomic, retain)NSArray *arrayList;

@end

নিউভিউকন্ট্রোল.আর

#import "NewViewController.h"

#import "ViewController.h"

@implementation NewViewController
@synthesize arrayList;

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return [arrayList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];      
    }
    // Configure the cell...
    cell.textLabel.text = [arrayList objectAtIndex:indexPath.row];
    return cell;


}

@end

সুতরাং আমরা এই পদ্ধতিতে একজন ভিউকন্ট্রোলার থেকে অন্য ভিউ নিয়ন্ত্রকের কাছে ডেটা পাস করতে পারি ...


8

এনএসপি প্রক্সির উপর ভিত্তি করে মডেল অবজেক্টস এবং মক অবজেক্টগুলির ধারণাটি যদি ব্যবহারকারী চয়ন করেন তবে তা বাতিল করা যেতে পারে যদি ডেটা প্রতিশ্রুতিবদ্ধ বা বাতিল করতে পারেন commit

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


8

আমি didSelectRowAtPathপদ্ধতিটি ব্যবহার করে এটি জটিল করার বিষয়ে অনেক লোককে দেখেছি । আমি আমার উদাহরণে কোর ডেটা ব্যবহার করছি।

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    //this solution is for using Core Data
    YourCDEntityName * value = (YourCDEntityName *)[[self fetchedResultsController] objectAtIndexPath: indexPath];

    YourSecondViewController * details = [self.storyboard instantiateViewControllerWithIdentifier:@"nameOfYourSecondVC"];//make sure in storyboards you give your second VC an identifier

    //Make sure you declare your value in the second view controller
    details.selectedValue = value;

    //Now that you have said to pass value all you need to do is change views
    [self.navigationController pushViewController: details animated:YES];

}

4 পদ্ধতির অভ্যন্তরে কোডের লাইন এবং আপনি সম্পন্ন করেছেন।


6

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

বাস্তবে, আমার মতে কয়েকটি সমাধানের প্রস্তাব দেওয়া হয়:

  • ডেটা এগিয়ে দেওয়ার জন্য:
    • স্টোরিবোর্ড এবং সেগগুলি ব্যবহার করার prepare(for:sender:)পদ্ধতিটি ওভাররাইড করুনUIViewController
    • প্রারম্ভিকের মাধ্যমে বা বৈশিষ্ট্যগুলির মাধ্যমে ডেটা পাস করুন যখন দেখান নিয়ামক সংক্রমণগুলি থটফ কোড সম্পাদন করে
  • পিছনে তথ্য পাস করার জন্য
    • অ্যাপ্লিকেশন ভাগ করে নেওয়ার স্থিতি আপডেট করুন (যা আপনি উপরের যে কোনও একটি পদ্ধতির সাথে ভিউ কন্ট্রোলারের মধ্যে এগিয়ে যেতে পারেন)
    • প্রতিনিধি ব্যবহার করুন
    • একটি অনিচ্ছাকৃত segue ব্যবহার করুন

সমাধানগুলি আমি ব্যবহার না করার পরামর্শ দিচ্ছি:

  • প্রতিনিধি ব্যবহারের পরিবর্তে সরাসরি পূর্ববর্তী নিয়ামককে উল্লেখ করা
  • একটি সিঙ্গলটনের মাধ্যমে ডেটা ভাগ করা
  • অ্যাপের প্রতিনিধি মাধ্যমে ডেটা পাস করা হচ্ছে
  • ব্যবহারকারীর ডিফল্ট মাধ্যমে ডেটা ভাগ করা
  • বিজ্ঞপ্তিগুলির মাধ্যমে ডেটা পাস করা

এই সমাধানগুলি স্বল্পমেয়াদে কাজ করা সত্ত্বেও, অনেক বেশি নির্ভরশীলতার পরিচয় দেয় যা অ্যাপ্লিকেশনের আর্কিটেকচারকে গারলেজ করবে এবং পরে আরও সমস্যা তৈরি করবে।

আগ্রহীদের জন্য, আমি কয়েকটি নিবন্ধ লিখেছি যা এই বিষয়গুলিকে আরও গভীরতার সাথে সম্বোধন করে এবং বিভিন্ন ত্রুটিগুলি হাইলাইট করে:

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.