শর্তসাপেক্ষে অ্যাপডেলিগেট থেকে স্টোরিবোর্ডে বিভিন্ন স্থানে শুরু করুন


107

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

// url request & response work fine, assume success is a BOOL here
// that indicates whether login was successful or not

if (success) {
          // 'push' main view controller
} else {
          // 'push' login view controller
}

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

সম্পাদনা করুন:

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    BOOL isLoggedIn = ...;    // got from server response

    NSString *segueId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
    UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:segueId];

    if (isLoggedIn) {
        [self.window setRootViewController:initViewController];
    } else {
        [(UINavigationController *)self.window.rootViewController pushViewController:initViewController animated:NO];
    }

    return YES;
}

পরামর্শ / উন্নতি স্বাগত!

উত্তর:


25

আমি ধরে নিয়েছি যে আপনার স্টোরিবোর্ডটি "মূল স্টোরিবোর্ড" হিসাবে সেট করা আছে ( UIMainStoryboardFileআপনার তথ্য.প্লেস্টের কী )। সেক্ষেত্রে, ইউআইকিট স্টোরিবোর্ডটি লোড করবে এবং এটি আপনার অ্যাপডেলিগেটে প্রেরণের আগে আপনার উইন্ডোর রুট ভিউ নিয়ন্ত্রণকারী হিসাবে এটির প্রাথমিক ভিউ কন্ট্রোলারটিকে সেট করবে application:didFinishLaunchingWithOptions:

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

আপনি আপনার উইন্ডোটির রুট ভিউ কন্ট্রোলারের জন্য জিজ্ঞাসা করতে পারেন এবং এতে performSegueWithIdentifier:sender:বার্তাটি প্রেরণ করতে পারেন:

NSString *segueId = success ? @"pushMain" : @"pushLogin";
[self.window.rootViewController performSegueWithIdentifier:segueId sender:self];

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

3
হ্যাঁ, আমার পক্ষেও কাজ করছে না। যদি এটি আপনার পক্ষে কাজ করে না তবে আপনি কেন এটি উত্তর হিসাবে চিহ্নিত করেছেন?
দাইদাই

3
আমি বিশ্বাস করি এটিই সঠিক উত্তর। আপনার 1. [[self window] makeKeyAndVisible]অ্যাপ্লিকেশন ডেলিগ্রেটে একটি উইন্ডো সম্পত্তি এবং 2. অ্যাপ্লিকেশন কল করতে হবে: শর্তসাপেক্ষ বিভাগগুলি করার আগে ডিনফিনিশলঞ্চিং উইথঅপশন: আপনার প্রয়োজন। ইউআইএপ্লিকেশনমেন () মেকের কেএএন্ডভিজিবল ম্যাসেজ করার জন্য মনে করা হয় তবে এটি কেবল ফিনিশের পরেই করা হয় ... বিকল্পগুলি: সমাপ্ত। বিশদগুলির জন্য অ্যাপল ডক্সে "ভিউ কন্ট্রোলারদের মধ্যে সমন্বয়মূলক প্রচেষ্টা" সন্ধান করুন।
edelaney05

এটি সঠিক ধারণা, তবে বেশ কার্যকর হয় না। কার্যক্ষম সমাধানের জন্য আমার উত্তরটি দেখুন See
ম্যাথু ফ্রেডরিক

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

170

আমি এখানে প্রস্তাবিত কিছু সমাধানের জন্য অবাক।

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

আপনার প্লাস্ট ফাইলটিতে স্টোরিবোর্ডটি কনফিগার না করা থাকলে আপনাকে উইন্ডো এবং রুট ভিউ নিয়ন্ত্রণকারী উভয়ই তৈরি করতে হবে :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    BOOL isLoggedIn = ...;    // from your server response

    NSString *storyboardId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
    UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:storyboardId];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initViewController;
    [self.window makeKeyAndVisible];

    return YES;
}

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

সেক্ষেত্রে এটি আরও সহজ:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    BOOL isLoggedIn = ...;    // from your server response

    NSString *storyboardId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";
    self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:storyboardId];

    return YES;
}

@ অ্যাডামরবাং স্পট চালু - আমি কেবল ওপি'র পরিবর্তনশীল নামগুলি অনুলিপি করেছিলাম, তবে আমি আমার উত্তরটি পরিষ্কার করার জন্য আপডেট করেছি। চিয়ার্স।
ফেব্রুবেন

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

জটিল শ্রেণিবিন্যাস নেভিগেশন নিয়ামককে না গিয়ে আমার পক্ষে এটি আরও স্বজ্ঞাত উপায়। এটি ভালবাসুন
ইলিয়ট ইয়াপ

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

1
সার্ভারের অনুরোধটি যদি অ্যাসিক্রোনাস হয়?
লিওর বার্গ

18

যদি আপনার স্টোরিবোর্ডের প্রবেশের বিন্দুটি না হয় UINavigationController:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {


    //Your View Controller Identifiers defined in Interface Builder
    NSString *firstViewControllerIdentifier  = @"LoginViewController";
    NSString *secondViewControllerIdentifier = @"MainMenuViewController";

    //check if the key exists and its value
    BOOL appHasLaunchedOnce = [[NSUserDefaults standardUserDefaults] boolForKey:@"appHasLaunchedOnce"];

    //if the key doesn't exist or its value is NO
    if (!appHasLaunchedOnce) {
        //set its value to YES
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"appHasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    //check which view controller identifier should be used
    NSString *viewControllerIdentifier = appHasLaunchedOnce ? secondViewControllerIdentifier : firstViewControllerIdentifier;

    //IF THE STORYBOARD EXISTS IN YOUR INFO.PLIST FILE AND YOU USE A SINGLE STORYBOARD
    UIStoryboard *storyboard = self.window.rootViewController.storyboard;

    //IF THE STORYBOARD DOESN'T EXIST IN YOUR INFO.PLIST FILE OR IF YOU USE MULTIPLE STORYBOARDS
    //UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YOUR_STORYBOARD_FILE_NAME" bundle:nil];

    //instantiate the view controller
    UIViewController *presentedViewController = [storyboard instantiateViewControllerWithIdentifier:viewControllerIdentifier];

    //IF YOU DON'T USE A NAVIGATION CONTROLLER:
    [self.window setRootViewController:presentedViewController];

    return YES;
}

যদি আপনার স্টোরিবোর্ডের প্রবেশের স্থানটি UINavigationControllerপ্রতিস্থাপন করে:

//IF YOU DON'T USE A NAVIGATION CONTROLLER:
[self.window setRootViewController:presentedViewController];

সঙ্গে:

//IF YOU USE A NAVIGATION CONTROLLER AS THE ENTRY POINT IN YOUR STORYBOARD:
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController pushViewController:presentedViewController animated:NO];

1
ভাল কাজ করেছেন। কেবল একটি মন্তব্য, তারা প্রাথমিকভাবে প্রবেশের পরে কেবল "ফার্স্টভিউ কনট্রোলারআইডেন্টিফায়ার" দেখাচ্ছে না? তাহলে কি তা উল্টানো উচিত নয়? appHasLaunchedOnce ? secondViewControllerIdentifier : firstViewControllerIdentifier;
অ্যামিয়ানাস

@ এম্মিয়ানাস আপনি সঠিক তাদের বিপরীত করা উচিত এবং আমি সম্পাদনা করেছি।
রাজ্জান

9

আপনার অ্যাপডেলিগেটের application:didFinishLaunchingWithOptionsপদ্ধতিতে, return YESলাইনের আগে , যুক্ত করুন:

UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
YourStartingViewController *yourStartingViewController = [[navigationController viewControllers] objectAtIndex:0];
[yourStartingViewController performSegueWithIdentifier:@"YourSegueIdentifier" sender:self];

প্রতিস্থাপন YourStartingViewControllerআপনার প্রকৃত প্রথম দৃশ্য নিয়ামক শ্রেণী (আপনি অগত্যা প্রদর্শিত হতে না চান) নামে এবংYourSegueIdentifier সেই আরম্ভকারী নিয়ামক এবং আপনি যেটি শুরু করতে চান তার মধ্যে সিগের আসল নাম করুন (সেগের পরে একটি) )।

ifআপনি যদি সর্বদা এটি ঘটে না চান তবে শর্তসাপেক্ষে কোডটি মোড়ানো ।


6

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

ইন AppDelegate.m :

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    MyCustomViewController *controller = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"MyCustomViewController"];

    // now configure the controller with a model, etc.

    self.window.rootViewController = controller;

    return YES;
}

স্ট্রিংটি ইনস্ট্যান্টিয়েট ভিউ কনট্রোলার উইথআইডেন্টিফায়ারকে দেওয়া স্টোরিবোর্ড আইডি বোঝায়, যা ইন্টারফেস বিল্ডারে সেট করা যেতে পারে:

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

প্রয়োজন অনুসারে কেবল এটিকে যুক্তিতে গুটিয়ে রাখুন।

আপনি যদি কোনও ইউআইএনএভিগেশন কন্ট্রোলার দিয়ে শুরু করেন তবে এই পদ্ধতি আপনাকে নেভিগেশন নিয়ন্ত্রণ দেয় না।

ইন্টারফেস বিল্ডারের মাধ্যমে সেট আপ করা নেভিগেশন কন্ট্রোলারের শুরু থেকে 'এগিয়ে যেতে', এই পদ্ধতিটি ব্যবহার করুন:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavigationController *navigation = (UINavigationController *) self.window.rootViewController;

    [navigation.visibleViewController performSegueWithIdentifier:@"my-named-segue" sender:nil];

    return YES;
}

4

প্রথম প্রদর্শিত লগইন স্ক্রিনটি কেন নেই, ব্যবহারকারী ইতিমধ্যে লগ ইন করেছেন কিনা তা পরীক্ষা করে সরাসরি পরের স্ক্রিনটি ধাক্কা দিয়ে দেবেন? ViewDidLoad এ সমস্ত।


2
এটি প্রকৃতপক্ষে কার্যকর হয়, তবে অ্যাপ্লিকেশনটি এখনও সার্ভারের প্রতিক্রিয়ার জন্য অপেক্ষা করছে যতক্ষণ না (লগইন সফল হয়েছিল কি না) লঞ্চ চিত্রটি দেখাই আমার লক্ষ্যগুলি। ঠিক যেমন ফেসবুক অ্যাপ্লিকেশন ...
মিমভি

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

3

এর দ্রুত বাস্তবায়ন:

আপনি UINavigationControllerস্টোরিবোর্ডে এন্ট্রি পয়েন্ট হিসাবে ব্যবহার করেন

let storyboard = UIStoryboard(name: "Main", bundle: nil)

var rootViewController = self.window!.rootViewController as! UINavigationController;

    if(loginCondition == true){

         let profileController = storyboard.instantiateViewControllerWithIdentifier("ProfileController") as? ProfileController  
         rootViewController.pushViewController(profileController!, animated: true) 
    }
    else {

         let loginController =   storyboard.instantiateViewControllerWithIdentifier("LoginController") as? LoginController 
         rootViewController.pushViewController(loginController!, animated: true) 
    }

1

এটিই সমাধান যা এনওএস 7 কাজ করে। প্রাথমিক লোডিংয়ে গতি বাড়ানোর জন্য এবং কোনও অপ্রয়োজনীয় লোড না করার জন্য আমার স্টোরিবোর্ডের ফাইলে আমার একটি সম্পূর্ণ ফাঁকা ইউআইভিউকন্ট্রোলার রয়েছে "ডামিওয়াই"। তারপরে আমি নিম্নলিখিত কোডটি ব্যবহার করতে পারি:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    NSString* controllerId = @"Publications";
    if (![NSUserDefaults.standardUserDefaults boolForKey:@"hasSeenIntroduction"])
    {
        controllerId = @"Introduction";
    }
    else if (![NSUserDefaults.standardUserDefaults boolForKey:@"hasDonePersonalizationOrLogin"])
    {
        controllerId = @"PersonalizeIntro";
    }

    if ([AppDelegate isLuc])
    {
        controllerId = @"LoginStart";
    }

    if ([AppDelegate isBart] || [AppDelegate isBartiPhone4])
    {
        controllerId = @"Publications";
    }

    UIViewController* controller = [storyboard instantiateViewControllerWithIdentifier:controllerId];
    self.window.rootViewController = controller;

    return YES;
}

0

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

মেইনভিউকন্ট্রোলারে:

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (isLoggedIn) {
        [self performSegueWithIdentifier:@"HomeSegue" sender:nil];
    } else {
        [self performSegueWithIdentifier:@"LoginSegue" sender:nil];
    }
}

হোম এবং লগইন দর্শন নিয়ন্ত্রকদের সাথে মেইনভিউকন্ট্রোলারের মধ্যে সেগগুলি তৈরির কথা মনে রাখবেন। আশাকরি এটা সাহায্য করবে. :)


0

বিভিন্ন পদ্ধতি বিভিন্ন চেষ্টা করার পরেও আমি এই সমস্যার সাথে এটি সমাধান করতে সক্ষম হয়েছি:

-(void)viewWillAppear:(BOOL)animated {

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) {
        self.view.hidden = YES;
    }
}

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

    // Check if user is already logged in
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    if ([[prefs objectForKey:@"log"] intValue] == 1) {
        [self performSegueWithIdentifier:@"homeSeg3" sender:self];
    }
}

-(void)viewDidUnload {
    self.view.hidden = NO;
}

আপনি যদি টেলরের সাথে খুব বেশি দূরে না থাকেন তবে আপনি আরও সহজ কিছুতে রিফ্যাক্টর করতে চাইতে পারেন। বিশদ জন্য আমার উত্তর দেখুন :)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.