আমি কীভাবে কোনও ইউআইএনএভিগেশন কন্ট্রোলার থেকে একটি দৃশ্য পপ করতে পারি এবং একটি ক্রিয়াকলাপের সাথে অন্যটির সাথে এটি প্রতিস্থাপন করতে পারি?


84

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

MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

[self retain];
[self.navigationController popViewControllerAnimated: NO];
[self.navigationController pushViewController: mevc animated: YES];
[self release];

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

এই সমস্যার আরও ভাল পদ্ধতির কী হতে পারে?

ধন্যবাদ, ম্যাট

উত্তর:


137

আমি আবিষ্কার করেছি যে viewControllersসম্পত্তিটির সাথে আপনাকে ম্যানুয়ালি হস্তক্ষেপ করার দরকার নেই । মূলত এই সম্পর্কে 2 টি কৌশলপূর্ণ জিনিস আছে।

  1. self.navigationControllerবর্তমানে নেভিগেশন কন্ট্রোলারের স্ট্যাকটিতে না nilথাকলে ফিরে আসবে self। সুতরাং আপনি এটির অ্যাক্সেস হারানোর আগে এটি স্থানীয় ভেরিয়েবলে সংরক্ষণ করুন।
  2. আপনার অবশ্যই retain(এবং সঠিকভাবে release) selfবা আপনি যে পদ্ধতিতে রয়েছেন তার মালিকানাধীন অবজেক্টটি বিচ্ছিন্ন হয়ে যাবে, যার ফলে অদ্ভুততা তৈরি হবে।

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

// locally store the navigation controller since
// self.navigationController will be nil once we are popped
UINavigationController *navController = self.navigationController;

// retain ourselves so that the controller will still exist once it's popped off
[[self retain] autorelease];

// Pop this controller and replace with another
[navController popViewControllerAnimated:NO];
[navController pushViewController:someViewController animated:NO];

গত রেখায় আপনি পরিবর্তন animatedকরতে YES, তারপর নতুন স্ক্রীনের আসলে সজীব এবং নিয়ামক আপনি শুধু popped আউট সজীব করবে। দেখতে বেশ সুন্দর লাগছে!


উজ্জ্বল! আরও ভাল সমাধান
এমএমবি

অসাধারণ. যদিও আমাকে [[স্বাবলম্বী] স্বতঃপরিচয়] কল করার দরকার নেই, এটি এখনও ঠিক কাজ করে।
iamj4de

4
সম্ভবত একটি সুস্পষ্ট সংযোজন, তবে আপনি পরে স্থানান্তর সক্রিয় করতে কোডটি অ্যানিমেশন ব্লকে উপরে রাখতে পারেন: [ইউআইভিউ সূচনা অ্যানিমেশন: @ "ফ্লিপ দেখুন" প্রসঙ্গ: শূন্য]; [ইউআইভিউ সেটঅ্যানিমেশনডিউরেশন: 0.80]; [ইউআইভিউ সেটএনিমেশন কার্কোভ: ইউআইভিউএনিমেশন কার্কোভেইসআইইনআউট]; [ইউআইভিউ সেটঅ্যানিমেশন ট্রান্সশন: ইউআইভিউএনিমেশন ট্রান্সনিশনফ্লিপফ্রাইম ফর রাইভ ফর: ভিউ: নেভকন্ট্রোলআরভিউ ক্যাশে: না]; [নেভকন্ট্রোলার পুশভিউকন্ট্রোলার: নতুনকন্ট্রোলার অ্যানিমেটেড: হ্যাঁ]; [ইউআইভিউ কমিট অ্যানিমেশনস];
মার্টিন

11
ঠিক রাখুন / অটোরিলেজ লাইনটি সরিয়ে এআরসি দিয়ে দুর্দান্ত কাজ করে।
আয়ান টেরেল

4
@ টমটারপিল্ড হ্যাঁ এই উত্তরটি প্রায় 5 বছরের পুরানো ... আমি মনে করি আইওএস 3 এর মতোই এটি হয়েছিল The এপিআইগুলি যথেষ্ট পরিবর্তন হয়েছে যে আমি নিশ্চিত নই যে এটিই এখন সেরা উত্তর answer
অ্যালেক্স ওয়েন

56

নিম্নলিখিত পদ্ধতিটি আমার কাছে ভাল লাগছে এবং এটিআরসি-র সাথেও ভাল কাজ করে:

UIViewController *newVC = [[UIViewController alloc] init];
// Replace the current view controller
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
[viewControllers removeLastObject];
[viewControllers addObject:newVC];
[[self navigationController] setViewControllers:viewControllers animated:YES];

4
@ লুকরোগারস, এটি আমার জন্য নিম্নলিখিত সতর্কতা সৃষ্টি করে: অপ্রত্যাশিত অবস্থায় নেভিগেশন ট্রানজিশন শেষ করে। নেভিগেশন বার সাবভিউ ট্রিটি ক্ষতিগ্রস্থ হতে পারে। এটিকে দমন করার কোনও উপায়?
জাইটসমান

এই সমাধানটি ব্যবহার করে আপনি পপওভারটি ওভাররাইট করেন। এবং ডিটেলভিউতে দেখানোর জন্য আপনার কোডটি পড়তে হবে:if(indexPath.row == 0){UIViewController *newVC = [[UIViewController alloc] init];newVC = [self.storyboard instantiateViewControllerWithIdentifier:@"Item1VC"]; NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[_detailViewController.navigationController viewControllers]]; [viewControllers removeLastObject];[viewControllers addObject:newVC]; [_detailViewController.navigationController setViewControllers:viewControllers animated:YES];}
এলওমাসিক আর্টস

আমি যা খুঁজছিলাম
JERC

9

অভিজ্ঞতা থেকে, আপনি viewControllersসরাসরি ইউআইএনএভিগেশন কন্ট্রোলারের সম্পত্তিতে গলগল করতে যাচ্ছেন । এর মতো কিছু কাজ করা উচিত:

MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

[[self retain] autorelease];
NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
self.navigationController.viewControllers = controllers;
[self.navigationController pushViewController:mevc animated: YES];

দ্রষ্টব্য: আমি রক্ষণ / প্রকাশকে একটি রক্ষণ / অটোরলেজে পরিবর্তন করেছি যেহেতু এটি কেবলমাত্র আরও দৃust় - যদি রক্ষণ / প্রকাশের মধ্যে যদি কোনও ব্যতিক্রম ঘটে তবে আপনি নিজেই ফাঁস হবেন, তবে অটোরেলেজ সেটির যত্ন নেয়।


7

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

আমি মনে করি যে একবার বর্তমান ভিউ কন্ট্রোলারটিকে স্ট্যাক থেকে সরিয়ে ফেলা হলে, তার নেভিগেশন নিয়ন্ত্রণকারী পদ্ধতিটি শূন্য হবে।

এখানে সমন্বিত কোড যা কাজ করে:

UINavigationController *navController = self.navigationController;
MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
navController.viewControllers = controllers;
[navController pushViewController:mevc animated: YES];

এটি আমাকে একটি কালো পুরো দেয়!
লৌমিক আর্টস

4

ধন্যবাদ, এটাই আমার দরকার ছিল। পৃষ্ঠার কার্লটি পেতে আমি এটি একটি অ্যানিমেশনে রেখেছি:

        MyEditViewController *mevc = [[MYEditViewController alloc] initWithGizmo: gizmo];

    UINavigationController *navController = self.navigationController;      
    [[self retain] autorelease];

    [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration: 0.7];
    [UIView setAnimationTransition:<#UIViewAnimationTransitionCurlDown#> forView:navController.view cache:NO];

    [navController popViewControllerAnimated:NO];
    [navController pushViewController:mevc animated:NO];

    [UIView commitAnimations];

০..6 সময়কাল দ্রুত, থ্রিজিএস এবং আরও নতুনদের জন্য ভাল, ০.৮ এখনও 3G এর জন্য কিছুটা খুব দ্রুত ..

জোহান


আপনার কোডটি আমি যা ব্যবহার করেছি ঠিক তাই! ধন্যবাদ একটি দ্রষ্টব্য: পৃষ্ঠা কার্ল সংক্রমণের সাথে আমি নীচের দিকে একটি সাদা শিল্পী পেয়েছি (কেন কে জানে) তবে ফ্লিপ সহ এটি দুর্দান্ত কাজ করেছে। যাইহোক, এটি দুর্দান্ত এবং কমপ্যাক্ট কোড!
ডেভিড এইচ

3

আপনি যদি পপটোরোটভিউ কনট্রোলার দ্বারা অন্য কোনও ভিউ কন্ট্রোলার দেখাতে চান তবে আপনাকে নিম্নলিখিতগুলি করতে হবে:

         UIViewController *newVC = [[WelcomeScreenVC alloc] initWithNibName:@"WelcomeScreenVC" bundle:[NSBundle mainBundle]];
            NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
            [viewControllers removeAllObjects];
            [viewControllers addObject:newVC];
            [[self navigationController] setViewControllers:viewControllers animated:NO];

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


1

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

[কন্ট্রোলাররা লাস্টবজেক্ট সরান];
দু'বার, আমার ক্ষেত্রে ভাল কাজ করেছে।

UINavigationController *navController = self.navigationController;

// retain ourselves so that the controller will still exist once it's popped off
[[self retain] autorelease];

searchViewController = [[SearchViewController alloc] init];    
NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];

[controllers removeLastObject];
// In my case I want to go up two, then push one..
[controllers removeLastObject];
navController.viewControllers = controllers;

NSLog(@"controllers: %@",controllers);
controllers = nil;

[navController pushViewController:searchViewController animated: NO];


1

এই UINavigationControllerউদাহরণ পদ্ধতিটি কাজ করতে পারে ...

নির্দিষ্ট ভিউ কন্ট্রোলার শীর্ষ ভিউ নিয়ন্ত্রক না হওয়া পর্যন্ত পপগুলি দেখুন নিয়ন্ত্রণগুলি এবং তারপরে প্রদর্শনটি আপডেট করে।

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated

1

এখানে আরও একটি পদ্ধতি যা ভিউকন্ট্রোলার অ্যারের সাথে সরাসরি গণ্ডগোলের প্রয়োজন হয় না। কন্ট্রোলারটি এখনও পপড হয়েছে কিনা তা পরীক্ষা করে দেখুন, যদি চাপ দিন।

TasksViewController *taskViewController = [[TasksViewController alloc] initWithNibName:nil bundle:nil];

if ([navigationController.viewControllers indexOfObject:taskViewController] == NSNotFound)
{
    [navigationController pushViewController:taskViewController animated:animated];
}
else
{
    [navigationController popToViewController:taskViewController animated:animated];
}

1
NSMutableArray *controllers = [self.navigationController.viewControllers mutableCopy];
    for(int i=0;i<controllers.count;i++){
       [controllers removeLastObject];
    }
 self.navigationController.viewControllers = controllers;

এটি কনসোলে আমার জন্য একটি সতর্কবার্তা সৃষ্টি করে - অপ্রত্যাশিত অবস্থায় নেভিগেশন রূপান্তর সমাপ্ত করে। নেভিগেশন বার সাবভিউ ট্রিটি ক্ষতিগ্রস্থ হতে পারে। এটিকে দমন করার কোনও উপায়?
জাইটসমান

1

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

ইউআইএনএভিগেশন কন্ট্রোলার + হেল্পার্স # ইমপোর্ট ort

@interface UINavigationController (Helpers)

- (UIViewController*) replaceTopViewControllerWithViewController: (UIViewController*) controller;

@end

ইউআইএনএভিগেশন কন্ট্রোলার + হেল্পার্স.এম
# ইমপোর্ট "ইউআইএনএভিগেশন কন্ট্রোলার + হেল্পার্স.হ।"

@implementation UINavigationController (Helpers)

- (UIViewController*) replaceTopViewControllerWithViewController: (UIViewController*) controller {
    UIViewController* topController = self.viewControllers.lastObject;
    [[topController retain] autorelease];
    UIViewController* poppedViewController = [self popViewControllerAnimated:NO];
    [self pushViewController:controller animated:NO];
    return poppedViewController;
}

@end

তারপরে আপনার ভিউ কন্ট্রোলার থেকে আপনি শীর্ষের ভিউটিকে নতুন করে এই জায়গায় প্রতিস্থাপন করতে পারেন:

[self.navigationController replaceTopViewControllerWithViewController: newController];

0

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


0

মনোোটুচ / জ্যামারিন আইওএসের জন্য:

ইউআইএসপ্লিটভিউ নিয়ন্ত্রণকারী শ্রেণীর ভিতরে;

UINavigationController mainNav = this._navController; 
//List<UIViewController> controllers = mainNav.ViewControllers.ToList();
mainNav.ViewControllers = new UIViewController[] { }; 
mainNav.PushViewController(detail, true);//to have the animation

0

বিকল্পভাবে,

আপনি ব্যবহার করতে পারেন categoryএড়াতে self.navigationControllerহতেnil পরেpopViewControllerAnimated

কেবল পপ এবং পুশ করুন, এটি বোঝা সহজ, অ্যাক্সেস করার দরকার নেই viewControllers....

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


0

উত্তরটি ঠিক নয় তবে কিছু পরিস্থিতিতে সহায়ক হতে পারে (উদাহরণস্বরূপ আমার):

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

প্রাথমিক সমস্যা এ -> সি (আমি সি পপ করতে চাই এবং খ দেখাচ্ছি, স্ট্যাকের বাইরে)

সম্ভাব্য সমাধান এ -> বি (অদৃশ্যভাবে ঠেলা) -> সি (যখন আমি সি পপ করি তখন আমি বি প্রদর্শন করা বা এটি পপ করতে পছন্দ করি)


0

অ্যানিমেশনটি রাখতে আমি এই সমাধানটি ব্যবহার করি।

[self.navigationController pushViewController:controller animated:YES];
NSMutableArray *newControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[newControllers removeObject:newControllers[newControllers.count - 2]];
[self.navigationController setViewControllers:newControllers];
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.