নেভিগেশন কন্ট্রোলারে ব্যাক বোতামের জন্য ক্রিয়া সেট করা


180

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

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 
                                  initWithTitle: @"Servers" 
                                  style:UIBarButtonItemStylePlain 
                                  target:self 
                                  action:@selector(home)];
self.navigationItem.backBarButtonItem = backButton;

যত তাড়াতাড়ি আমি এটিটি আমার ক্রিয়াকলাপটি leftBarButtonItemঅন ​​করে navigationItemদিয়েছিলাম ঠিক ততক্ষণে বোতামটি তীরযুক্ত ব্যাকটির পরিবর্তে প্লেইন বৃত্তাকার মত দেখাচ্ছে:

self.navigationItem.leftBarButtonItem = backButton;

রুট ভিউতে ফিরে যাওয়ার আগে আমি কীভাবে এটি আমার কাস্টম অ্যাকশনটিকে কল করতে পারি? ডিফল্ট ব্যাক ক্রিয়াটি ওভাররাইট করার কোনও উপায় আছে, বা এমন কোনও পদ্ধতি রয়েছে যা দর্শন ছাড়ার সময় সর্বদা ডাকা হয় ( viewDidUnloadতা করে না)?


কর্ম: @selector (বাড়ি)]; একটি দরকার: নির্বাচক কর্মের পরে: @ নির্বাচক (হোম :)]; অন্যথায় এটি কাজ করবে না
পার্টিসফট

7
@ পার্টিশোফ্ট এটি সত্য নয় যতক্ষণ না কোলনের সাথে পদ্ধতিটি ঘোষণা করা হয়। বোতাম কল নির্বাচনকারীরা কোনও প্যারামিটার নেয় না তা পুরোপুরি বৈধ।
mbm29414


3
কেন অ্যাপল ব্যাক বোতামের মতো স্টাইলের আকারযুক্ত একটি বোতাম সরবরাহ করবে না? বেশ সুস্পষ্ট মনে হয়।
জনকে

উত্তর:


363

আপনি যেখানে প্রেসটি সনাক্ত করতে চান সেখানে ভিউ কন্ট্রোলারে এটি রাখার চেষ্টা করুন:

-(void) viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
       // back button was pressed.  We know this is true because self is no longer
       // in the navigation stack.  
    }
    [super viewWillDisappear:animated];
}

1
এটি একটি চটজলদি, পরিষ্কার, সুন্দর এবং খুব সুচিন্তিত কাজ
বলিভা

6
+1 দুর্দান্ত হ্যাক, তবে পপ অ্যানিমেশনের উপর নিয়ন্ত্রণ সরবরাহ করে না
ম্যাটমে

3
যদি আমি একটি বোতামের মাধ্যমে প্রতিনিধিকে একটি বার্তা প্রেরণ করি এবং প্রতিনিধিটি নিয়ামকটিকে পপ করে - তবে আমার পক্ষে কাজ করে না this
SAHM

21
আরেকটি সমস্যা হ'ল ব্যবহারকারী যদি পিছনের বোতামটি টিপেন বা আপনি প্রগতিগতভাবে [সেল্ফ-নেভিগেশন কন্ট্রোলার পপভিউ কনট্রোলার অ্যানিমেটেড: হ্যাঁ] বলে থাকেন তবে আপনি পৃথক করতে পারবেন না
চেজ রবার্টস

10
কেবলমাত্র একটি এফওয়াইআই: সুইফ্ট সংস্করণ:if (find(self.navigationController!.viewControllers as! [UIViewController],self)==nil)
hEADcRASH

177

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

-(BOOL) navigationShouldPopOnBackButton {
    if(needsShowConfirmation) {
        // Show confirmation alert
        // ...
        return NO; // Ignore 'Back' button this time
    }
    return YES; // Process 'Back' button click and Pop view controler
}

নমুনা অ্যাপ্লিকেশনটি ডাউনলোড করুন


16
এটি আপনার নিজের কাস্টম ইউআইবাটন ব্যবহার করার চেয়ে ভাল এবং সহজ এবং আমি সবচেয়ে সহজ সমাধানটি দেখেছি। ধন্যবাদ!
ramirogm

4
navigationBar:shouldPopItem:একটি বেসরকারি পদ্ধতি যেহেতু এটি একটা অংশ নয় UINavigationBarDelegateপ্রোটোকল।
ওয়ানগ্রি

1
তবে ইউআইএনএভিগেশন কন্ট্রোলার ইতিমধ্যে ডেলিগেটটি (বাস্তবায়ন YES) বাস্তবায়ন করে ? নাকি ভবিষ্যতে হবে? সাবক্ল্যাসিং সম্ভবত একটি নিরাপদ বিকল্প
স্যাম

8
আমি সবেমাত্র আইওএস 7.1 এ এটি (দুর্দান্ত শীতল বিটিডাব্লু) বাস্তবায়ন করেছি এবং লক্ষ্য করেছি যে NOফিরে বোতামটি ফিরে আসার পরে অক্ষম অবস্থায় থাকে (দৃষ্টিভঙ্গি, কারণ এটি এখনও ইভেন্টগুলি গ্রহণ করে এবং প্রতিক্রিয়া দেখায়)। আমি নেভিগেশন বারের মতামতগুলির মাধ্যমে চেকটিতে একটি elseবিবৃতি যোগ করে shouldPopএবং সাইকেল চালিয়ে, এবং alphaঅ্যানিমেশন ব্লকের ভিতরে প্রয়োজনে মানটি 1 এ সেট করে এটি ব্যবহার করেছি : gist.github.com/idevsoftware/9754057
বলিভা

2
এটি আমি দেখেছি এমন এক সেরা এক্সটেনশন। তোমাকে অনেক ধন্যবাদ.
শ্রীকান্ত

42

Amagrammer এর বিপরীতে বলেছেন, এটি সম্ভব। আপনার সাবক্লাস করতে হবে আপনার navigationController। আমি এখানে সমস্ত কিছু ব্যাখ্যা করেছি (উদাহরণস্বরূপ কোড সহ)।


অ্যাপলের ডকুমেন্টেশন ( বিকাশকারী.অ্যাপল .com/ আইফোন / লাইবারি / ডকুমেন্টেশন / ইউআইকিট / )) বলে যে "এই শ্রেণিটি সাবক্লাসিংয়ের উদ্দেশ্যে নয়"। যদিও তারা এটার অর্থ কী তা আমি নিশ্চিত নই - তাদের অর্থ "আপনার সাধারণত এটি করার দরকার নেই" বা তাদের অর্থ হতে পারে "আপনি যদি আমাদের নিয়ামকের সাথে ঝামেলা করেন তবে আমরা আপনার অ্যাপ্লিকেশনটিকে প্রত্যাখ্যান করব" ...
কুবা সুদার

এটি অবশ্যই এটি করার একমাত্র উপায়। হ্যাঁ, আমি আপনাকে আরও পয়েন্ট পুরস্কার দিতে পারি!
অ্যাডাম এবারবাচ

1
আপনি কি এই পদ্ধতিটি ব্যবহার করে কোনও দৃশ্যকে প্রস্থান করতে বাধা দিতে পারবেন? আপনি যদি ভিউটি প্রস্থান না করতে চান তবে আপনি কী পপভিউ কনট্রোলার অ্যানিমেটেড পদ্ধতিতে ফিরে আসবেন?
জোসেফ এইচ

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

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

15

সুইফ্ট সংস্করণ:

( https://stackoverflow.com/a/19132881/826435 এর )

আপনার ভিউ কন্ট্রোলারে আপনি কেবল একটি প্রোটোকলের সাথে সামঞ্জস্য করেন এবং আপনার যা প্রয়োজন ক্রিয়া সম্পাদন করুন:

extension MyViewController: NavigationControllerBackButtonDelegate {
    func shouldPopOnBackButtonPress() -> Bool {
        performSomeActionOnThePressOfABackButton()
        return false
    }
}

তারপরে একটি শ্রেণী তৈরি করুন, বলুন NavigationController+BackButtonএবং কেবল নীচের কোডটি অনুলিপি করুন:

protocol NavigationControllerBackButtonDelegate {
    func shouldPopOnBackButtonPress() -> Bool
}

extension UINavigationController {
    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        // Prevents from a synchronization issue of popping too many navigation items
        // and not enough view controllers or viceversa from unusual tapping
        if viewControllers.count < navigationBar.items!.count {
            return true
        }

        // Check if we have a view controller that wants to respond to being popped
        var shouldPop = true
        if let viewController = topViewController as? NavigationControllerBackButtonDelegate {
            shouldPop = viewController.shouldPopOnBackButtonPress()
        }

        if (shouldPop) {
            DispatchQueue.main.async {
                self.popViewController(animated: true)
            }
        } else {
            // Prevent the back button from staying in an disabled state
            for view in navigationBar.subviews {
                if view.alpha < 1.0 {
                    UIView.animate(withDuration: 0.25, animations: {
                        view.alpha = 1.0
                    })
                }
            }

        }

        return false
    }
}

হতে পারে আমি কিছু মিস করেছি, তবে এটি আমার পক্ষে কাজ করবে না, পদ্ধতিটি কার্য সম্পাদনের কয়েকটি অ্যাকশনঅনপ্রেস অফফ্যাকব্যাক বাটন কখনই ডাকা হয় না
টারভি

@ ফ্লোরেন্টব্রেটন হয়ত কোনও ভুল বুঝাবুঝি? shouldPopOnBackButtonPressযতক্ষণ না কোনও বাগ রয়েছে ততক্ষণ কল করা উচিত। performSomeActionOnThePressOfABackButtonএটি কেবলমাত্র একটি তৈরি পদ্ধতি যা বিদ্যমান নেই।
kgaidis

আমি এটি বুঝতে পেরেছিলাম, এজন্য performSomeActionOnThePressOfABackButtonপিছনের বোতামটি টিপলে আমি একটি নির্দিষ্ট ক্রিয়া সম্পাদন করার জন্য আমার কন্ট্রোলারে একটি পদ্ধতি তৈরি করেছি, তবে এই পদ্ধতিটি কখনই ডাকা হয়নি, ক্রিয়াটি একটি সাধারণ ব্যাক রিটার্ন
টারভি

1
আমার পক্ষেও কাজ করছে না। কাঁপপ পদ্ধতিটি কখনই ডাকা হয় না। আপনি কোথাও একটি প্রতিনিধি সেট করেছেন?
টিম অটিন

@ টিমআউটিন আমি কেবল এটি আবার পরীক্ষা করেছি এবং দেখে মনে হচ্ছে কিছু পরিবর্তন হয়েছে। মূল অংশ বুঝতে একটি যে UINavigationController, navigationBar.delegateগৌণ নিয়ামক সেট করা হয়। সুতরাং পদ্ধতিগুলি কল করা উচিত। যাইহোক, সুইফটে, আমি তাদের কল করতে পারি না, এমনকি একটি সাবক্লাসেও। তবে আমি তাদের উদ্দেশ্যমূলক-সি-তে ডেকে আনার জন্য করেছি, সুতরাং আমি আপাতত উদ্দেশ্যমূলক-সি সংস্করণটি ব্যবহার করব। একটি সুইফট বাগ হতে পারে।
kgaidis

5

সরাসরি করা সম্ভব নয়। কয়েকটি বিকল্প আছে:

  1. আপনার নিজস্ব কাস্টম তৈরি করুন UIBarButtonItemযা টেপে বৈধ হয় এবং পরীক্ষা পাস হলে পপ হয়
  2. একটি ব্যবহার ফর্ম ক্ষেত্র বিষয়বস্তু যাচাই UITextField, প্রতিনিধি পদ্ধতি যেমন -textFieldShouldReturn:, যা বলা হয় পরে Returnবা Doneবোতাম কীবোর্ডে টেপা হলে

প্রথম বিকল্পের নেতিবাচক দিকটি হ'ল পিছনের বোতামের বাম-নির্দেশক-তীর শৈলীর একটি কাস্টম বার বোতাম থেকে অ্যাক্সেস করা যায় না। সুতরাং আপনাকে একটি চিত্র ব্যবহার করতে হবে বা নিয়মিত স্টাইলের বোতামটি নিয়ে যেতে হবে।

দ্বিতীয় বিকল্পটি দুর্দান্ত কারণ আপনি পাঠ্য ক্ষেত্রটি ডেলিগেট পদ্ধতিতে ফিরে পেয়েছেন, তাই আপনি ডেলিগেট কল-ব্যাক পদ্ধতিতে প্রেরিত নির্দিষ্ট পাঠ্য ক্ষেত্রে আপনার বৈধতা যুক্তিকে টার্গেট করতে পারেন।


5

কিছু থ্রেডিং কারণে, @ হান্সপিনেকার্স দ্বারা উল্লিখিত সমাধানটি আমার পক্ষে সঠিক ছিল না, তবে আমি পিছনের বোতামটিতে একটি স্পর্শ ধরার খুব সহজ উপায় খুঁজে পেয়েছি এবং এটি যদি এখানে ঘন্টার পর ঘন্টা প্রতারণা এড়াতে পারে তবে আমি এখানে এটি লিখে ফেলতে চাই case অন্য কেউ. কৌশলটি সত্যিই সহজ: আপনার ইউআইএনএভিগেশনবারে একটি স্বাক্ষর হিসাবে স্বচ্ছ ইউআইবাটনটি যুক্ত করুন এবং তার জন্য আপনার নির্বাচকদের সেট করুন যেন এটি আসল বোতাম! মনোোটুচ এবং সি # ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে তবে উদ্দেশ্য-সি-তে অনুবাদটি খুঁজে পাওয়া খুব কঠিন হবে না।

public class Test : UIViewController {
    public override void ViewDidLoad() {
        UIButton b = new UIButton(new RectangleF(0, 0, 60, 44)); //width must be adapted to label contained in button
        b.BackgroundColor = UIColor.Clear; //making the background invisible
        b.Title = string.Empty; // and no need to write anything
        b.TouchDown += delegate {
            Console.WriteLine("caught!");
            if (true) // check what you want here
                NavigationController.PopViewControllerAnimated(true); // and then we pop if we want
        };
        NavigationController.NavigationBar.AddSubview(button); // insert the button to the nav bar
    }
}

মজাদার ঘটনা: পরীক্ষার উদ্দেশ্যে এবং আমার নকল বোতামটির জন্য ভাল মাত্রা সন্ধান করার জন্য, আমি এর পটভূমির রঙটি নীলতে সেট করেছি ... এবং এটি পিছনের বোতামের পিছনে দেখায় ! যাইহোক, এটি এখনও মূল বোতামটি লক্ষ্য করে কোনও স্পর্শ ধরে।


3

এই কৌশলটি আপনাকে অ্যানিমেশন চলাকালীন কোনও ভিউ কন্ট্রোলারের শিরোনামকে প্রভাবিত না করে বা পিছনের বোতামের পাঠ্য পরিবর্তন না দেখে "পিছনে" বোতামটির পাঠ্য পরিবর্তন করতে দেয়।

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

UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];   
temporaryBarButtonItem.title = @"Back";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;
[temporaryBarButtonItem release];

3

সহজ রাস্তা

আপনি ইউআইএনএভিগেশন কন্ট্রোলারের প্রতিনিধি পদ্ধতিগুলি ব্যবহার করতে পারেন। willShowViewControllerআপনার ভিসির পিছনের বোতামটি টিপলে পদ্ধতিটি ডাকা হয় do পিছনে বিটিএন চাপলে আপনি যা চান তাই করুন

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

নিশ্চিত হয়ে নিন যে আপনার ভিউ কন্ট্রোলার উত্তরাধিকার সূত্রে প্রাপ্ত নেভিগেশন নিয়ন্ত্রকের প্রতিনিধি হিসাবে নিজেকে সেট করে এবং ইউআইএনএভিগেশন কন্ট্রোলারডেলিগেট প্রোটোকলের সাথে সম্মতি জানায়
জাস্টিন মিলো ২

3

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

extension UIViewController {
    func navigationShouldPopOnBackButton() -> Bool {
        return true
    }
}

extension UINavigationController {

    func navigationBar(navigationBar: UINavigationBar, shouldPopItem item: UINavigationItem) -> Bool {
        if let vc = self.topViewController {
            if vc.navigationShouldPopOnBackButton() {
                self.popViewControllerAnimated(true)
            } else {
                for it in navigationBar.subviews {
                    let view = it as! UIView
                    if view.alpha < 1.0 {
                        [UIView .animateWithDuration(0.25, animations: { () -> Void in
                            view.alpha = 1.0
                        })]
                    }
                }
                return false
            }
        }
        return true
    }

}

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

সত্য হিসাবে প্রত্যাশিত হলে এটি পুরোপুরি ফিরে যায়
প্যাভারউইস

@Pawriwes এখানে একটি সমাধান আমি লিখেছেন আমার জন্য কাজ বলে মনে হয় আছে: stackoverflow.com/a/34343418/826435
kgaidis

3

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

-(void) overrideBack{

    UIButton *transparentButton = [[UIButton alloc] init];
    [transparentButton setFrame:CGRectMake(0,0, 50, 40)];
    [transparentButton setBackgroundColor:[UIColor clearColor]];
    [transparentButton addTarget:self action:@selector(backAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.navigationController.navigationBar addSubview:transparentButton];


}

নিম্নলিখিত পদ্ধতিতে প্রয়োজন অনুযায়ী এখন একটি কার্যকারিতা সরবরাহ করুন:

-(void)backAction:(UIBarButtonItem *)sender {
    //Your functionality
}

এটি যা করে তা হ'ল পিছনের বোতামটি স্বচ্ছ বোতামটি আবরণ করা;)


3

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

override func viewDidLoad(){
   super.viewDidLoad()
   
   navigationItem.leftBarButton = .init(title: "Go Back", ... , action: #selector(myCutsomBackAction) 

   ...
 
}

========================================

আগের প্রতিক্রিয়া নির্মাণের UIAlert মধ্যে Swift5 একটি অ্যাসিঙ্ক্রোনাস উপায়


protocol NavigationControllerBackButtonDelegate {
    func shouldPopOnBackButtonPress(_ completion: @escaping (Bool) -> ())
}

extension UINavigationController: UINavigationBarDelegate {
    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
      
        if viewControllers.count < navigationBar.items!.count {
            return true
        }
        
        // Check if we have a view controller that wants to respond to being popped
        
        if let viewController = topViewController as? NavigationControllerBackButtonDelegate {
            
            viewController.shouldPopOnBackButtonPress { shouldPop in
                if (shouldPop) {
                    /// on confirm => pop
                    DispatchQueue.main.async {
                        self.popViewController(animated: true)
                    }
                } else {
                    /// on cancel => do nothing
                }
            }
            /// return false => so navigator will cancel the popBack
            /// until user confirm or cancel
            return false
        }else{
            DispatchQueue.main.async {
                self.popViewController(animated: true)
            }
        }
        return true
    }
}

আপনার নিয়ামক


extension MyController: NavigationControllerBackButtonDelegate {
    
    func shouldPopOnBackButtonPress(_ completion: @escaping (Bool) -> ()) {
    
        let msg = "message"
        
        /// show UIAlert
        alertAttention(msg: msg, actions: [
            
            .init(title: "Continuer", style: .destructive, handler: { _ in
                completion(true)
            }),
            .init(title: "Annuler", style: .cancel, handler: { _ in
                completion(false)
            })
            ])
   
    }

}

ভিউকন্ট্রোলারস কোড <নেভিগেশনবার.সাইটস!। অ্যাকাউন্ট ount সত্য প্রত্যাবর্তন করুন} চেক করুন, তাহলে কী হচ্ছে তা সম্পর্কে বিশদ সরবরাহ করতে পারেন?
এইচ

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

2

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

আপনি নিয়মিত বোতামটি তৈরি করে এবং ডিফল্ট ব্যাক বোতামটি গোপন করে (তীর ছাড়া) কাছে পেতে পারেন:

self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Servers" style:UIBarButtonItemStyleDone target:nil action:nil] autorelease];
self.navigationItem.hidesBackButton = YES;

2
হ্যাঁ সমস্যা হ'ল আমি চাই এটি স্বাভাবিক ব্যাক বোতামের মতো দেখতে চাই, প্রথমে আমার কাস্টম অ্যাকশনটি কল করা দরকার ...
তোতা

2

একটি সহজ উপায় আছে শুধু subclassing দ্বারা এর প্রতিনিধি পদ্ধতি এর UINavigationBarএবং ওভাররাইড ShouldPopItemপদ্ধতি


আমার মনে হয় আপনি ইউআইএনএভিগেশন কন্ট্রোলার ক্লাসটি সাবক্লাস বলতে চাইছেন এবং একটি হোল্ডপপ আইটেম পদ্ধতি প্রয়োগ করবেন। এটা আমার জন্য ভাল কাজ করছে। তবে, সেই পদ্ধতিটি আপনার প্রত্যাশা মতো কেবল হ্যাঁ বা কোনও ফেরত দেওয়া উচিত নয়। একটি ব্যাখ্যা এবং সমাধান এখানে পাওয়া যায়: stackoverflow.com/a/7453933/462162
arlomedia

2

ওয়ানগ্রয়ের সমাধানটি নিরাপদ নয় Apple অ্যাপল, https://developer.apple.com/library/ios/docamentation/Cocoa/Concepual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html এর অফিসিয়াল ডকুমেন্ট অনুসারে আমাদের এগুলি করা এড়ানো উচিত।

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


2

সুইফট ব্যবহার:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if self.navigationController?.topViewController != self {
        print("back button tapped")
    }
}

আইওএস 10 এবং সম্ভবত এর আগে হিসাবে এটি আর কাজ করছে না।
মারে সাগল

2

ন্যাভিগেশন বার ব্যাক বোতাম ইভেন্টটি ফায়ার হওয়ার আগে ধরার জন্য এখানে @ একের জবাবের সুইফট 3 সংস্করণ রয়েছে । যেমন UINavigationBarDelegateব্যবহার করা যায় না UIViewController, আপনাকে ডেলিগেট তৈরি করতে হবে navigationBar shouldPopযা ডাকা হলে ট্রিগার করা হবে ।

@objc public protocol BackButtonDelegate {
      @objc optional func navigationShouldPopOnBackButton() -> Bool 
}

extension UINavigationController: UINavigationBarDelegate  {

    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {

        if viewControllers.count < (navigationBar.items?.count)! {                
            return true
        }

        var shouldPop = true
        let vc = self.topViewController

        if vc.responds(to: #selector(vc.navigationShouldPopOnBackButton)) {
            shouldPop = vc.navigationShouldPopOnBackButton()
        }

        if shouldPop {
            DispatchQueue.main.async {
                self.popViewController(animated: true)
            }
        } else {
            for subView in navigationBar.subviews {
                if(0 < subView.alpha && subView.alpha < 1) {
                    UIView.animate(withDuration: 0.25, animations: {
                        subView.alpha = 1
                    })
                }
            }
        }

        return false
    }
}

এবং তারপরে, আপনার দর্শনে নিয়ন্ত্রকের প্রতিনিধি ফাংশন যুক্ত করুন:

class BaseVC: UIViewController, BackButtonDelegate {
    func navigationShouldPopOnBackButton() -> Bool {
        if ... {
            return true
        } else {
            return false
        }        
    }
}

আমি বুঝতে পেরেছি যে ব্যবহারকারীরা ফিরে যেতে চান কিনা তা স্থির করতে আমরা প্রায়শই একটি সতর্কতা নিয়ামক যুক্ত করতে চাই। যদি তাই হয়, আপনি সবসময় করতে পারেন return falseমধ্যে navigationShouldPopOnBackButton()ফাংশন এবং ভালো কিছু করে আপনার ভিউ নিয়ামক বন্ধ:

func navigationShouldPopOnBackButton() -> Bool {
     let alert = UIAlertController(title: "Warning",
                                          message: "Do you want to quit?",
                                          preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { UIAlertAction in self.yes()}))
            alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { UIAlertAction in self.no()}))
            present(alert, animated: true, completion: nil)
      return false
}

func yes() {
     print("yes")
     DispatchQueue.main.async {
            _ = self.navigationController?.popViewController(animated: true)
        }
}

func no() {
    print("no")       
}

আমি একটি ত্রুটি Value of type 'UIViewController' has no member 'navigationShouldPopOnBackButton' পাচ্ছি : যখন আমি আপনার কোডটি সংকলনের চেষ্টা করব , তখনও লাইনটির জন্য if vc.responds(to: #selector(v..., একটি self.topViewControllerreturnsচ্ছিক প্রদান করে এবং এর জন্য একটি সতর্কতাও রয়েছে।
শঙ্কর

এফডব্লিউআইডাব্লু, আমি কোডটি তৈরি করে ঠিক করে দিয়েছি: let vc = self.topViewController as! MyViewControllerএবং এখনও পর্যন্ত এটি ঠিকঠাকভাবে কাজ করছে বলে মনে হচ্ছে। আপনি যদি বিশ্বাস করেন যে এটি একটি সঠিক পরিবর্তন, আপনি কোডটি সম্পাদনা করতে পারেন। এছাড়াও, যদি আপনি মনে করেন এটি করা উচিত নয় তবে আমি কেন তা জানতে পেরে খুশি হব। এই কোডের জন্য ধন্যবাদ। আপনার উত্তরটি সম্ভবত এই সম্পর্কে একটি ব্লগ পোস্ট লিখতে হবে, কারণ এই উত্তরটি ভোট অনুযায়ী নিচে দেওয়া হয়েছে।
শঙ্কর

@ সংকরপ যে কারণে আপনি এই ত্রুটিটি পেয়েছেন তা হ'ল আপনি MyViewControllerমেনে চলতে পারেন না BackButtonDelegate। মোড়ক মোড়ানো জোর করার পরিবর্তে, guard let vc = self.topViewController as? MyViewController else { return true }সম্ভাব্য ক্রাশ এড়াতে আপনার করা উচিত ।
ললিয়লেট

ধন্যবাদ। আমি মনে করি গার্ডের বিবৃতি হওয়া উচিত: guard let vc = self.topViewController as? MyViewController else { self.popViewController(animated: true) return true }পর্দাটি সঠিকরূপে কাস্ট করা যায় না সে ক্ষেত্রে ডান পৃষ্ঠায় চলেছে কিনা তা নিশ্চিত করার জন্য। আমি এখন বুঝতে পারি যে navigationBarফাংশনটি সমস্ত ভিসিগুলিতে ডাকা হয় এবং কেবল ভিউকন্ট্রোলার নয় যেখানে এই কোডটি বিদ্যমান। আপনার উত্তরেও কোডটি আপডেট করা ভাল হবে? ধন্যবাদ।
শঙ্কর

2

সুইফট 4 আইওএস 11.3 সংস্করণ:

এটি https://stackoverflow.com/a/34343418/4316579 থেকে kgaidis থেকে উত্তর তৈরি করে

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

আশা করি এটি এমন লোকদের সহায়তা করে যাঁরা ভাবছেন যে তাদের এক্সটেনশানটি আর কাজ করে না।

extension UINavigationController: UINavigationBarDelegate {
    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {

    }
}

1

আপনি বর্তমানে 'নিল' রেখে যাচ্ছেন এমন লক্ষ্য এবং ক্রিয়া ভেরিয়েবলগুলি ব্যবহার করে, আপনার সংরক্ষণ-সংলাপগুলিকে তারে সক্ষম করতে সক্ষম হওয়া উচিত যাতে বোতামটি "নির্বাচিত" হওয়ার পরে সেগুলি ডাকা হয়। দেখুন, এটি অদ্ভুত মুহুর্তগুলিতে ট্রিগার হতে পারে।

আমি বেশিরভাগ Amagrammer এর সাথে একমত, তবে আমি মনে করি না তীর পছন্দ অনুসারে বোতামটি তৈরি করা এত কঠিন হবে hard আমি কেবল পিছনের বোতামটির নাম পরিবর্তন করব, একটি স্ক্রিন শট নেব, প্রয়োজনীয় বোতামের আকারের ফটোশপ করব এবং এটি আপনার বোতামের শীর্ষে চিত্র হবে।


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

হ্যাঁ, ব্যাকবার্ট বাটন আইটেমের সাথে সংযুক্ত থাকলে ক্রিয়াগুলি ট্রিগার করা হয় না। আমি জানি না এটি কোনও বাগ বা কোনও বৈশিষ্ট্য কিনা; এটাও সম্ভব যে অ্যাপলও জানে না। ফটোশপিংয়ের অনুশীলনের ক্ষেত্রে আবারও আমি সতর্ক থাকব যে অ্যাপল কোনও ক্যানোনিকাল চিহ্নের অপব্যবহারের জন্য অ্যাপ্লিকেশনটিকে প্রত্যাখ্যান করবে।
Amagrammer

শিরোনাম: এই উত্তরটি সদৃশ থেকে মার্জ করা হয়েছে।
শোগ 9

1

আপনি নেভিগেশনবার রাইট বাটন আইটেমটি অ্যাক্সেস করার চেষ্টা করতে পারেন এবং এর নির্বাচক সম্পত্তি সেট করতে পারেন ... একটি রেফারেন্স ইউআইবারবাটন আইটেম রেফারেন্স , এটি অন্য একটি জিনিস যা এই ডিফল্ট কাজটি ডিফল্ট করবে তা যদি, ন্যাভি বারের ডান বোতাম আইটেমটি একটি কাস্টম ইউআইবারবার বাটন আইটেমে সেট করে যে আপনি এর নির্বাচক তৈরি এবং সেট করুন ... আশা করি এটি সাহায্য করবে


শিরোনাম: এই উত্তরটি সদৃশ থেকে মার্জ করা হয়েছে।
শোগ 9

1

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


শিরোনাম: এই উত্তরটি সদৃশ থেকে মার্জ করা হয়েছে।
শোগ 9

1

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

@interface MyViewController : UIViewController
{
    UIControl   *backCover;
    BOOL        inhibitBackButtonBOOL;
}
@end

@implementation MyViewController
-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Cover the back button (cannot do this in viewWillAppear -- too soon)
    if ( backCover == nil ) {
        backCover = [[UIControl alloc] initWithFrame:CGRectMake( 0, 0, 80, 44)];
#if TARGET_IPHONE_SIMULATOR
        // show the cover for testing
        backCover.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.15];
#endif
        [backCover addTarget:self action:@selector(backCoverAction) forControlEvents:UIControlEventTouchDown];
        UINavigationBar *navBar = self.navigationController.navigationBar;
        [navBar addSubview:backCover];
    }
}

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [backCover removeFromSuperview];
    backCover = nil;
}

- (void)backCoverAction
{
    if ( inhibitBackButtonBOOL ) {
        NSLog(@"Back button aborted");
        // notify the user why...
    } else {
        [self.navigationController popViewControllerAnimated:YES]; // "Back"
    }
}
@end

শিরোনাম: এই উত্তরটি সদৃশ থেকে মার্জ করা হয়েছে।
শোগ 9

1

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

যা আদর্শ নয় তা হ'ল এই বোতামটি <তীরটি পায় না এবং পূর্ববর্তী ভিসি শিরোনামটি এগিয়ে রাখে না, তবে আমি মনে করি এটি পরিচালনা করা যায়। আমার উদ্দেশ্যগুলির জন্য, আমি নতুন ব্যাক বোতামটি একটি "সম্পন্ন" বোতামে সেট করেছি যাতে এর উদ্দেশ্যটি পরিষ্কার।

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

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


1

দ্রুতগতি

override func viewWillDisappear(animated: Bool) {
    let viewControllers = self.navigationController?.viewControllers!
    if indexOfArray(viewControllers!, searchObject: self) == nil {
        // do something
    }
    super.viewWillDisappear(animated)
}

func indexOfArray(array:[AnyObject], searchObject: AnyObject)-> Int? {
    for (index, value) in enumerate(array) {
        if value as UIViewController == searchObject as UIViewController {
            return index
        }
    }
    return nil
}

1

এই পদ্ধতিটি আমার পক্ষে কাজ করেছে (তবে "পিছনে" বোতামটিতে "<" চিহ্ন থাকবে না):

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIBarButtonItem* backNavButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                                                      style:UIBarButtonItemStyleBordered
                                                                     target:self
                                                                     action:@selector(backButtonClicked)];
    self.navigationItem.leftBarButtonItem = backNavButton;
}

-(void)backButtonClicked
{
    // Do something...
    AppDelegate* delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    [delegate.navController popViewControllerAnimated:YES];
}

1

@ ওয়ানগ্রাইয়ের উত্তরের সুইফট সংস্করণ

protocol RequestsNavigationPopVerification {
    var confirmationTitle: String { get }
    var confirmationMessage: String { get }
}

extension RequestsNavigationPopVerification where Self: UIViewController {
    var confirmationTitle: String {
        return "Go back?"
    }

    var confirmationMessage: String {
        return "Are you sure?"
    }
}

final class NavigationController: UINavigationController {

    func navigationBar(navigationBar: UINavigationBar, shouldPopItem item: UINavigationItem) -> Bool {

        guard let requestsPopConfirm = topViewController as? RequestsNavigationPopVerification else {
            popViewControllerAnimated(true)
            return true
        }

        let alertController = UIAlertController(title: requestsPopConfirm.confirmationTitle, message: requestsPopConfirm.confirmationMessage, preferredStyle: .Alert)

        alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
            dispatch_async(dispatch_get_main_queue(), {
                let dimmed = navigationBar.subviews.flatMap { $0.alpha < 1 ? $0 : nil }
                UIView.animateWithDuration(0.25) {
                    dimmed.forEach { $0.alpha = 1 }
                }
            })
            return
        })

        alertController.addAction(UIAlertAction(title: "Go back", style: .Default) { _ in
            dispatch_async(dispatch_get_main_queue(), {
                self.popViewControllerAnimated(true)
            })
        })

        presentViewController(alertController, animated: true, completion: nil)

        return false
    }
}

এখন যে কোনও নিয়ামকের মধ্যে, কেবল সামঞ্জস্য করুন RequestsNavigationPopVerificationএবং এই আচরণটি ডিফল্টরূপে গৃহীত হয়।


1

ব্যবহার isMovingFromParentViewController

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(true)

    if self.isMovingFromParentViewController {
        // current viewController is removed from parent
        // do some work
    }
}

আপনি কীভাবে এটির পিছনে বোতামটি টেপ করেছিলেন তা প্রমাণ করতে পারেন?
মারে সাগল

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

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

1

@ উইলিয়ামের উত্তর সঠিক, তবে যদি ব্যবহারকারী একটি সোয়াইপ-টু-গো-ইশার ইঙ্গিত শুরু করে তবে viewWillDisappearপদ্ধতিটি বলা হয় এবং এমনকি selfনেভিগেশন স্ট্যাকের মধ্যে থাকবে না (এটি self.navigationController.viewControllersধারণ করবে না self), এমনকি যদি সোয়াইপ করেও সম্পূর্ণ হয়নি এবং ভিউ কন্ট্রোলারটি আসলে পপড হয় না। সুতরাং, সমাধানটি হ'ল:

  1. সোয়াইপ-টু-গো-ব্যাক অঙ্গভঙ্গিটি অক্ষম করুন viewDidAppearএবং কেবল ব্যাক বোতামটি ব্যবহারের মাধ্যমে মঞ্জুরি দিন:

    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
    {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }
  2. বা viewDidDisappearপরিবর্তে কেবল পরিবর্তে ব্যবহার করুন:

    - (void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
        if (![self.navigationController.viewControllers containsObject:self])
        {
            // back button was pressed or the the swipe-to-go-back gesture was
            // completed. We know this is true because self is no longer
            // in the navigation stack.
        }
    }

0

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

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if ((self.isMovingFromParentViewController || self.isBeingDismissed)
      && !self.isPoppingProgrammatically) {
    // Do your stuff here
  }
}

প্রোগ্রামটিমেটিকভাবে পপ করার আগে আপনাকে সেই সম্পত্তিটি আপনার নিয়ামকের সাথে যুক্ত করতে হবে এবং এটি YES এ সেট করতে হবে:

self.isPoppingProgrammatically = YES;
[self.navigationController popViewControllerAnimated:YES];

0

এটি করার নতুন উপায় খুঁজে পেয়েছে:

উদ্দেশ্য গ

- (void)didMoveToParentViewController:(UIViewController *)parent{
    if (parent == NULL) {
        NSLog(@"Back Pressed");
    }
}

দ্রুতগতি

override func didMoveToParentViewController(parent: UIViewController?) {
    if parent == nil {
        println("Back Pressed")
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.