在视图控制器之间传递数据


無口君哦哦
2025-02-09 04:52:06 (1月前)
  1. 在数组中保存UITableView上的选择,但是如何将其传递回上一个


数据
</跨度>
输入表单视图,以便它可以与另一个一起保存

数据
</跨度>


核心
</跨度>

数据
</跨度>
提交我是iOS和Objective-C以及整个MVC范例的新手,我坚持以下内容:

我有一个观点,作为一个

数据
</跨度>
输入表单,我想给用户选择多个选项

23 条回复
  1. 0# 解天 | 2019-08-31 10-32




    将一个ViewController传递给另一个ViewController有3种类型
    视图控制器。





    1. 编程方式


    2. Segue公司


    3. UserDefaults

    4. </醇>



      演示项目链接在这里
      </强>

      1. -
      2. <a href="https://github.com/kamanijasmin13/Swift-Pass-data-between-viewcontrollers" rel="nofollow noreferrer">
      3. https://github.com/kamanijasmin13/Swift-Pass-data-between-viewcontrollers
      4. </A>




      编程方式
      </强>






      Segue公司
      </强>






      UserDefaults
      </强>






      演示项目链接在这里
      </强>

      1. -
      2. <a href="https://github.com/kamanijasmin13/Swift-Pass-data-between-viewcontrollers" rel="nofollow noreferrer">
      3. https://github.com/kamanijasmin13/Swift-Pass-data-between-viewcontrollers
      4. </A>


  2. 1# 易米烊光 | 2019-08-31 10-32



    有很多方法可以做到这一点,选择正确的方法很重要。可能最大的架构决策之一取决于如何在整个应用程序中共享或访问模型代码。



    我写了一篇关于这篇文章的博文:

    共享模型代码

    。这是一个简短的总结:



    共享数据



    一种方法是在视图控制器之间共享指向模型对象的指针。




    • 在视图控制器(在导航或标签栏控制器中)进行强力迭代以设置数据


    • 在prepareForSegue(如果是故事板)或init(如果是程序员)中设置数据



    因为准备segue是最常见的一个例子:




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

    2. </code>


    独立访问



    另一种方法是一次处理一个充满数据的屏幕,而不是将视图控制器彼此耦合,将每个视图控制器耦合到它们可以独立获得的单个数据源。



    我见过这种方式最常见的方式是

    独生子

    实例。所以如果你的单身对象是

    DataAccess

    您可以在UIViewController的viewDidLoad方法中执行以下操作:




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

    2. </code>


    还有一些附加工具可以帮助传递数据:




    • 关键价值观察


    • NSNotification


    • 核心数据


    • NSFetchedResultsController


    • 数据源



    核心数据



    Core Data的优点在于它具有反向关系。因此,如果您只想给NotesViewController提供notes对象,因为它与其他类似笔记本的东西有反向关系。如果您需要在NotesViewController中的笔记本上的数据,您可以通过执行以下操作返回对象图:




    1. let notebookName = note.notebook.name

    2. </code>


    在我的博客文章中阅读更多相关信息:

    共享模型代码


  3. 2# 楊♡ | 2019-08-31 10-32



    我很长时间都在寻找这个解决方案,Atlast我发现了它。首先声明SecondViewController.h文件中的所有对象




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

    2. </code>


    现在在您的实现文件中为这些对象分配内存



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

    3. </code>


    现在你已经分配了内存

    Array

    和对象。现在你可以在推动之前填充内存

    ViewController



    转到SecondViewController.h并编写两个方法




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

    2. </code>


    在实现文件中,您可以实现该功能




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

    2. </code>


    期待你的

    CustomObject

    必须有一个setter函数。



    现在你的基本工作已经完成。去你要推的地方

    SecondViewController

    并做以下的事情




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

    2. </code>


    注意拼写错误。


  4. 3# 易米烊光 | 2019-08-31 10-32



    如果要将数据从一个控制器传递给其他控制器,请尝试使用此代码



    FirstViewController.h




    1. @property (nonatomic, retain) NSString *str;

    2. </code>


    SecondViewController.h




    1. @property (nonatomic, retain) NSString *str1;

    2. </code>


    FirstViewController.m



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

    3.  [super viewDidLoad];
    4. }

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

    6. </code>

  5. 4# 淋了一整夜的雨 | 2019-08-31 10-32



    有多种方法可以将数据接收到iOS中的不同类。例如 -




    1. 分配另一个类后直接初始化。


    2. 委派 - 用于传回数据


    3. 通知 - 用于一次向多个类广播数据


    4. 储蓄

      NSUserDefaults

      1. - 稍后访问它
      2. </LI>
      3. <LI>
      4. 单身人士课程
      5. </LI>
      6. <LI>
      7. 数据库和其他存储机制,如plist等。
      8. </LI>

      </醇>


      但是对于将值传递给在当前类中完成分配的其他类的简单方案,最常见和首选的方法是在分配后直接设置值。这样做如下: -



      我们可以使用两个控制器来理解它 -

      Controller1和Controller2
      </强>



      假设在Controller1类中,您要创建Controller2对象并使用传递的String值推送它。这可以这样做: -



      1.   - (void)pushToController2 {
      2. Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
      3. [obj passValue:@"String"];
      4. [self pushViewController:obj animated:YES];
      5. }

      6. </code>


      在Controller2类的实现中,将有以下功能 -




      1. @interface Controller2 : NSObject

      2. @property (nonatomic , strong) NSString* stringPassed;

      3. @end

      4. @implementation Controller2

      5. @synthesize stringPassed = _stringPassed;

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

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

        • @end

        • </code>


        您也可以使用与此类似的方式直接设置Controller2类的属性:



        1.   - (void)pushToController2 {
        2. Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
        3. [obj setStringPassed:@"String"];  
        4. [self pushViewController:obj animated:YES];
        5. }

        6. </code>


        要传递多个值,您可以使用多个参数,例如: -




        1. Controller2 *obj = [[Controller2 alloc] initWithNib:@”Controller2 bundle:nil];
          [obj passValue:@锟斤拷String1锟斤拷 andValues:objArray withDate:date];

        2. </code>


        或者,如果需要传递超过3个与常用功能相关的参数,则可以将值存储到Model类中,并将该modelObject传递给下一个类




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

        2. Controller2 *obj = [[Controller2 alloc] initWithNib:@”Controller2 bundle:nil];
          [obj passmodel: modelObject];

        3. </code>


        所以,如果你想 -




        1. 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.

        2. </code>


        希望这可以帮助


    5. 5# Let us fly | 2019-08-31 10-32



      经过更多的研究,似乎协议和代表是正确的/ Apple首选方式。



      我最终使用了这个例子




      在视图控制器和其他对象之间共享数据

      @ iPhone Dev SDK



      工作得很好,并允许我在我的视图之间前后传递一个字符串和一个数组。



      感谢你的帮助


    6. 6# v-star*위위 | 2019-08-31 10-32



      如果你想从一个viewController发送数据到另一个viewController,这是一个方法:



      假设我们有viewControllers:viewControllerA和viewControllerB



      现在在viewControllerB.h中




      1. @interface viewControllerB : UIViewController {

      2. NSString string;
        NSArray
        array;

      3. }

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




      在viewControllerB.m中



      1. #import "viewControllerB.h"
      2. @implementation viewControllerB

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

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

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

        • }

        • </code>


        在viewControllerA.m中



        1.   #import "viewControllerA.h"
        2. 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];

          • }

          • </code>


          这就是你可以在不设置任何委托的情况下将数据从viewControllerA传递给viewControllerB的方法。 ;)


        3. 7# 只怕再见是故人 | 2019-08-31 10-32



          我见过很多人用这个来复杂化

          didSelectRowAtPath

          方法。我在我的例子中使用Core Data。



          1.   - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
          2. //this solution is for using Core Data
          3. YourCDEntityName * value = (YourCDEntityName *)[[self fetchedResultsController] objectAtIndexPath: indexPath];
          4. YourSecondViewController * details = [self.storyboard instantiateViewControllerWithIdentifier:@"nameOfYourSecondVC"];//make sure in storyboards you give your second VC an identifier
          5. //Make sure you declare your value in the second view controller
          6. details.selectedValue = value;
          7. //Now that you have said to pass value all you need to do is change views
          8. [self.navigationController pushViewController: details animated:YES];
          9. }

          10. </code>


          方法内的4行代码就完成了。


        4. 8# ࿏自ོ༾由ོ༽人͙⃡⌇ | 2019-08-31 10-32



          这个问题有很多答案,提供了许多不同的方法来执行确实可行的视图控制器通信,但我没有看到任何提到哪个实际上最好使用哪些以及哪些方法要避免。



          在实践中,我认为只推荐几种解决方案:




          • 要传递数据:

            1. <UL>
            2. <LI>
            3. 覆盖
            4. <code>
            5. prepare(for:sender:)
            6. </code>
            7. 的方法
            8. <code>
            9. UIViewController
            10. </code>
            11. 使用故事板和segues时
            12. </LI>
            13. <LI>
            14. 在代码执行视图控制器转换时,通过初始化程序或通过属性传递数据
            15. </LI>
            16. </UL>
            17. </LI>
            18. <LI>
            19. 向后传递数据
            20. <UL>
            21. <LI>
            22. 更新应用程序共享状态(您可以使用上述任一方法在视图控制器之间传递)
            23. </LI>
            24. <LI>
            25. 使用代表团
            26. </LI>
            27. <LI>
            28. 使用unwind segue
            29. </LI>
            30. </UL>
            31. </LI>



          解决方案我建议不要使用:




          • 直接引用先前的控制器而不是使用委托


          • 通过单例共享数据


          • 通过app委托传递数据


          • 通过用户默认值共享数据


          • 通过通知传递数据



          这些解决方案尽管在短期内工作,但会引入太多的依赖关系,这些依赖关系会破坏应用程序的体系结构并在以后产生更多问题。



          对于那些感兴趣的人,我写了一些文章,更深入地解决了这些问题,并突出了各种缺点:



        5. 9# 日耀九洲 | 2019-08-31 10-32



          OP没有提到视图控制器,但是有很多答案,我想要了解LLVM的一些新功能允许在想要将数据从一个视图控制器传递到另一个视图控制器时更容易得到一些结果。



          故事板segues,ARC和LLVM块使我比以往更容易。上面提到的故事板和细分的一些答案已经但仍然依赖于委托。定义委托肯定有效,但有些人可能会发现传递指针或代码块更容易。



          使用UINavigators和segues,可以通过简单的方法将信息传递给从属控制器并获取信息。 ARC使指向NSObjects派生的东西的指针变得简单,所以如果你想让subservient控制器为你添加/更改/修改一些数据,请将指针传递给一个可变实例。块使传递操作变得容易,因此如果您希望子服务控制器在更高级别的控制器上调用操作,则将其传递给块。您可以定义块以接受对您有意义的任意数量的参数。您还可以设计API以使用多个块,如果更适合的话。



          以下是segue胶水的两个简单例子。第一个是直接显示传递输入的一个参数,第二个输出。




          1. // 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];
              }




          第二个示例显示为第二个参数传递回调块。我喜欢使用块,因为它使相关的细节在源中保持紧密 - 更高级别的源。



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

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

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

          5. // This parameter allows the next controller to pass back results.
            resultsBlock:^(id results) {

          6.    // This callback could be as involved as you like.
          7.    // It can use Grand Central Dispatch to have work done on another thread for example.
          8.   [self setResultsFromNextController:results];
          9. }];
            }



        6. 10# 撩心 | 2019-08-31 10-32




          NewsViewController
          </强>



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

          3. newsDetailView.newsHeadlineStr = newsObj.newsHeadline;

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

          5. </code>



          NewsDetailViewController.h
          </强>




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

          2. </code>



          NewsDetailViewController.m
          </强>




          1. @synthesize newsHeadlineStr;

          2. </code>

        7. 11# 圈圈红 | 2019-08-31 10-32



          您可以将数据保存在App委托中,以便跨应用程序中的视图控制器访问它。您所要做的就是创建一个app delegate的共享实例




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

          2. </code>



          例如
          </强>



          如果你宣布一个

          NSArray object *arrayXYZ

          然后你可以在任何视图控制器中访问它

          appDelegate.arrayXYZ


        8. 12# 不想吃东西 | 2019-08-31 10-32



          将数据从ViewController 2(目标)传递回viewController 1(Source)是更有趣的事情。
          假设你使用storyBoard那些是我发现的所有方法:




          • 代表


          • 通知


          • 用户默认值


          • 独生子



          这些已经在这里讨论过。



          我发现还有更多方法:



          1. - 使用块回调:
          2. </强>



          在…中使用它

          prepareForSegue

          VC1中的方法




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

          2. </code>


          1. - 使用故事板放松(退出)
          2. </强>



          在VC 1中使用UIStoryboardSegue参数实现一个方法,如下所示:




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

          2. </code>


          在storyBoard勾选“返回”按钮到绿色退出
          按钮(展开)的vc。
          现在你有一个“回归”的segue,所以你可以使用
          VC2和的prepareForSegue中的destinationViewController属性
          在VC1返回之前更改VC1的任何属性。





          • 使用故事板Undwind(退出)的另一种选择 - 你可以
            使用您在VC1中编写的方法




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

            2.     </code>
            3.   </pre>
            4.   <P>
            5.     VC1prepareForSegue中,您可以更改要共享的任何属性。
            6.   </p>
            7. </LI>


          在两个展开选项中,您可以设置按钮的标记属性并将其签入
          prepareForSegue。



          希望我在讨论中加入一些内容。



          :)干杯。


        9. 13# نسر الصحراء | 2019-08-31 10-32




          在FirstViewController和SecondViewController之间传递数据,如下所示
          </强>



          例如:



          FirstViewController字符串值为




          1. StrFirstValue = @”first”;

          2. </code>


          所以我们可以使用下面的步骤在第二类中传递这个值



          1&gt;我们需要在SecondViewController.h文件中创建字符串对象




          1. NSString *strValue;

          2. </code>


          2&gt;需要在.h文件中声明属性如下面的声明




          1. @property (strong, nonatomic) NSString *strSecondValue;

          2. </code>


          3&gt;需要在头部声明下面的FirstViewController.m文件中合成该值




          1. @synthesize strValue;

          2. </code>


          在FirstViewController.h中:




          1. @property (strong, nonatomic) NSString *strValue;

          2. </code>


          4&gt;在FirstViewController中,我们从哪个方法导航到第二个视图,请在该方法中编写下面的代码。




          1. SecondViewController *secondView= [[SecondViewController alloc]
            initWithNibName:@”SecondViewController bundle:[NSBundle MainBundle]];

          2. [secondView setStrSecondValue:StrFirstValue];

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

          4. </code>

        10. 14# 故人 | 2019-08-31 10-32



          这不是这样做的方法,你应该使用委托,我假设我们有两个视图控制器ViewController1和ViewController2,这个检查是在第一个,当它的状态发生变化时,你想在ViewController2中做一些事情,到以正确的方式实现,你应该做到以下:



          将新文件添加到项目中(Objective-C Protocol)文件 - &gt;新的,现在将它命名为ViewController1Delegate或任何你想要的,并在@interface@end指令之间写出这些




          1. @optional

            • (void)checkStateDidChange:(BOOL)checked;




          现在转到ViewController2.h并添加



          1. #import "ViewController1Delegate.h"



          然后将其定义更改为



          1. @interface ViewController2: UIViewController<ViewController1Delegate>



          现在转到ViewController2.m并在实现中添加:



          1. - (void)checkStateDidChange:(BOOL)checked {
          2. if (checked) {

          3.      // Do whatever you want here
          4.      NSLog(@"Checked");
          5. }
            else {

          6.      // Also do whatever you want here
          7.      NSLog(@"Not checked");
          8. }
            }




          现在转到ViewController1.h并添加以下属性:



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



          现在如果你在一些事件之后在ViewController2中创建ViewController1,那么你应该这样使用NIB文件:



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




          现在你已经完成了设置,只要你在ViewController1中检测到检查事件发生了变化,你所要做的就是下面的内容



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



          如果我不能正确理解你的问题,请告诉我是否有任何不清楚的事情。


        11. 15# 不丶离 | 2019-08-31 10-32



          当您使用.xib文件时,委派是执行此类操作的唯一解决方案,但上述所有答案均适用于

          storyboard

          对于.xibs文件,您需要使用委托。这是唯一的解决方案。



          另一个解决方案是使用单例类模式初始化它一次并在整个应用程序中使用它。


        12. 16# 滔滔江水 | 2019-08-31 10-32



          我知道这是一个被打败的主题,但对于那些希望用SWIFT倾斜回答这个问题的人并想要一个简单的例子,这里是我使用segue来绕过数据的传递方法。



          它类似于上面但没有按钮,标签等。只需简单地将数据从一个视图传递到下一个视图。




          设置故事板
          </强>



          有三个部分。




          1. 寄件人


          2. 塞格


          3. 收件人

          4. </醇>


            这是一个非常简单的视图布局,它们之间有一个segue。












            这是发件人的设置












            这是接收器的设置。












            最后,segue的设置。













            视图控制器
            </强>



            我们保持这个简单,所以没有按钮,而不是动作,我们只是在应用程序加载时将数据从发送方移动到接收方,然后将传输的值输出到控制台。



            此页面获取最初加载的值并将其传递。




            1. //
              // ViewControllerSender.swift
              // PassDataBetweenViews
              //
              // Created by Chris Cantley on 8/25/15.
              // Copyright (c) 2015 Chris Cantley. All rights reserved.
              //

            2. import UIKit

            3. class ViewControllerSender: UIViewController {

            4. // THE STUFF - put some info into a variable
            5. let favoriteMovie = "Ghost Busters"
            6. override func viewDidAppear(animated: Bool) {
            7.     // PASS IDENTIFIER - go to the recieving view controller.
            8.     self.performSegueWithIdentifier("goToReciever", sender: self)
            9. }
            10. override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            11.     //GET REFERENCE - ...to the receiver view.
            12.     var viewControllerReceiver = segue.destinationViewController as? ViewControllerReceiver
            13.     //PASS STUFF - pass the variable along to the target.
            14.     viewControllerReceiver!.yourFavMovie = self.favoriteMovie
            15. }
            16. }

            17. </code>


            此页面在加载时只将变量的值发送到控制台。到此为止,我们最喜欢的电影应该在那个变量中。




            1. //
              // ViewControllerReceiver.swift
              // PassDataBetweenViews
              //
              // Created by Chris Cantley on 8/25/15.
              // Copyright (c) 2015 Chris Cantley. All rights reserved.
              //

            2. import UIKit

            3. class ViewControllerReceiver: UIViewController {

            4. //Basic empty variable waiting for you to pass in your fantastic favorite movie.
            5. var yourFavMovie = ""
            6. override func viewDidLoad() {
            7.     super.viewDidLoad()
            8.     //And now we can view it in the console.
            9.     println("The Movie is \(self.yourFavMovie)")
            10. }
            11. }

            12. </code>


            如果您想使用segue并且没有导航控制器下的页面,那么就可以解决这个问题。



            一旦运行它应该自动切换到接收器视图并将值从发送器传递到接收器,在控制台中显示值。







        13. 17# 咿呀哟 | 2019-08-31 10-32



          有多种共享数据的方法。





          1. 您始终可以使用共享数据

            NSUserDefaults

            。根据您选择的键设置要共享的值,并从中获取值

            NSUserDefault

            与下一个视图控制器中的该键相关联。




            1. [[NSUserDefaults standardUserDefaults] setValue:value forKey:key]
              [[NSUserDefaults standardUserDefaults] objectForKey:key]

            2.     </code>
            3.   </pre>
            4. </LI>
            5. <LI>
            6.   <P>
            7.     您可以在中创建一个属性
            8.      <code>
            9.       viewcontrollerA
            10.     </code>
            11.     。创建一个对象
            12.      <code>
            13.       viewcontrollerA
            14.     </code>
            15.      
            16.      <code>
            17.       viewcontrollerB
            18.     </code>
            19.      并为该属性分配所需的值。
            20.   </p>
            21. </LI>
            22. <LI>
            23.   <P>
            24.     您也可以为此创建自定义委托。
            25.   </p>
            26. </LI>
            27. </醇>

        14. 18# 离线请留言 | 2019-08-31 10-32



          我喜欢基于NSProxy的Model对象和Mock对象的想法,如果可以取消用户选择的内容,则提交或丢弃数据。



          由于它是单个对象或几个对象,所以很容易传递数据,如果你让我们说UINavigationController控制器,你可以保持对模型内部的引用,所有被推动的视图控制器都可以直接从导航控制器访问它。


        15. 19# ⑩Ⅵ嵗D夨憶 | 2019-08-31 10-32



          接下来创建属性

          view controller .h

          并定义getter和setter。



          加上这个

          property

          在nextVC.h上的nextVC




          1. @property (strong, nonatomic) NSString *indexNumber;

          2. </code>






          @synthesize indexNumber;

          在NextVC.m中



          最后




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

          2. vc.indexNumber=@”123”;

          3. [self.navigationController vc animated:YES];

          4. </code>

        16. 20# v-star*위위 | 2019-08-31 10-32



          这个问题似乎在stackoverflow上非常受欢迎,所以我想我会尝试给出一个更好的答案来帮助像我这样的iOS世界中的人们。



          我希望这个答案足够清楚,让人们理解并且我没有错过任何东西。




          传递数据
          </强>



          将数据从另一个视图控制器传递到视图控制器。如果要将对象/值从一个视图控制器传递到另一个可能正在推送到导航堆栈的视图控制器,则可以使用此方法。



          对于这个例子,我们将有

          ViewControllerA



          ViewControllerB



          传递一个

          BOOL

          来自的价值

          ViewControllerA



          ViewControllerB

          我们会做以下事情。







          1. ViewControllerB.h

            为…创建一个属性

            BOOL




            1. @property (nonatomic, assign) BOOL isSomethingEnabled;

            2.     </code>
            3.   </pre>
            4. </LI>
            5. <LI>
            6.   <P>
            7.     
            8.      <code>
            9.       ViewControllerA
            10.     </code>
            11.      你需要告诉它
            12.      <code>
            13.       ViewControllerB
            14.     </code>
            15.      所以用一个
            16.   </p>
            17.    <pre>
            18.     <code>
            19.       #import "ViewControllerB.h"
            20.     </code>
            21.   </pre>
            22.   <P>
            23.     然后你想加载视图的地方,例如。
            24.      <code>
            25.       didSelectRowAtIndex
            26.     </code>
            27.      或者一些
            28.      <code>
            29.       IBAction
            30.     </code>
            31.      你需要设置属性
            32.      <code>
            33.       ViewControllerB
            34.     </code>
            35.      在你把它推到导航堆栈之前。
            36.   </p>
            37.    <pre>
            38.     <code>
            39.       ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
            40. viewControllerB.isSomethingEnabled = YES;
              [self pushViewController:viewControllerB animated:YES];

            41.     </code>
            42.   </pre>
            43.   <P>
            44.     这将设置
            45.      <code>
            46.       isSomethingEnabled
            47.     </code>
            48.      
            49.      <code>
            50.       ViewControllerB
            51.     </code>
            52.      
            53.      <code>
            54.       BOOL
            55.     </code>
            56.      
            57.      <code>
            58.       YES
            59.     </code>
            60.     
            61.   </p>
            62. </LI>
            63. </醇>



              使用Segues传递数据
              </强>



              如果您使用的是故事板,则最有可能使用segues,并且需要使用此过程来传递数据。这与上面的类似,但不是在推送视图控制器之前传递数据,而是使用一个名为的方法




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

            64. </code>


            65. 所以传递一个

              BOOL



              ViewControllerA



              ViewControllerB

              我们会做以下事情:







              1. ViewControllerB.h

                为…创建一个属性

                BOOL




                @property (nonatomic, assign) BOOL isSomethingEnabled;

              1.     </code>
              1.   </pre>
              1. </LI>
              1. <LI>
              1.   <P>
              1.     
              1.      <code>
              1.       ViewControllerA
              1.     </code>
              1.      你需要告诉它
              1.      <code>
              1.       ViewControllerB
              1.     </code>
              1.      所以用一个
              1.   </p>
              1.    <pre>
              1.     <code>
              1.       #import "ViewControllerB.h"
              1.     </code>
              1.   </pre>
              1. </LI>
              1. <LI>
              1.   <P>
              1.     从中创建一个segue
              1.      <code>
              1.       ViewControllerA
              1.     </code>
              1.      
              1.      <code>
              1.       ViewControllerB
              1.     </code>
              1.      在故事板上并给它一个标识符,在这个例子中我们称之为
              1.      <code>
              1.       "showDetailSegue"
              1.     </code>
              1.   </p>
              1. </LI>
              1. <LI>
              1.   <P>
              1.     接下来,我们需要添加方法
              1.      <code>
              1.       ViewControllerA
              1.     </code>
              1.      当执行任何segue时调用,因此我们需要检测调用哪个segue然后执行某些操作。在我们的例子中,我们将检查
              1.      <code>
              1.       "showDetailSegue"
              1.     </code>
              1.      如果那已经完成,我们将通过我们的
              1.      <code>
              1.       BOOL
              1.     </code>
              1.      价值
              1.      <code>
              1.       ViewControllerB
              1.     </code>
              1.   </p>
              1.    <pre>
              1.     <code>
              1.       -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
              1. if([segue.identifier isEqualToString:@"showDetailSegue"]){
              1.     ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
              1.     controller.isSomethingEnabled = YES;
              1. }
              1. }

              1.     </code>
              1.   </pre>
              1.   <P>
              1.     如果您将视图嵌入导航控制器中,则需要将上述方法稍微更改为以下方法
              1.   </p>
              1.    <pre>
              1.     <code>
              1.       -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
              1. if([segue.identifier isEqualToString:@"showDetailSegue"]){
              1.     UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
              1.     ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
              1.     controller.isSomethingEnabled = YES;
              1. }
              1. }

              1.     </code>
              1.   </pre>
              1.   <P>
              1.     这将设置
              1.      <code>
              1.       isSomethingEnabled
              1.     </code>
              1.      
              1.      <code>
              1.       ViewControllerB
              1.     </code>
              1.      
              1.      <code>
              1.       BOOL
              1.     </code>
              1.      
              1.      <code>
              1.       YES
              1.     </code>
              1.     
              1.   </p>
              1. </LI>
              1. </醇>



                传递数据
                </强>



                从中传回数据

                ViewControllerB



                ViewControllerA

                你需要使用

                协议和代表

                要么



                后者可以用作回调的松散耦合机制。



                要做到这一点,我们将做

                ViewControllerA

                代表

                ViewControllerB

                。这允许

                ViewControllerB

                发回信息给

                ViewControllerA

                使我们能够发回数据。



                对于

                ViewControllerA

                成为一名代表

                ViewControllerB

                它必须符合

                ViewControllerB

                我们必须指定的协议。这说明

                ViewControllerA

                它必须实现哪些方法。







                1. ViewControllerB.h

                  以下

                1.       #import
                1.     </code>
                1.     ,但在上面
                1.      <code>
                1.       @interface
                1.     </code>
                1.      你指定协议。
                1.   </p>
                1.    <pre>
                1.     <code>
                1.       @class ViewControllerB;
                1. @protocol ViewControllerBDelegate

                    • (void)addItemViewController:(ViewControllerB )controller didFinishEnteringItem:(NSString )item;
                      @end

                    •   </code>
                    • </pre>

                    • <P>
                    •   接下来还在
                    •    <code>
                    •     ViewControllerB.h
                    •   </code>
                    •    你需要设置一个
                    •    <code>
                    •     delegate
                    •   </code>
                    •    财产和合成
                    •    <code>
                    •     ViewControllerB.m
                    •   </code>
                    • </p>
                    •  <pre>
                    •   <code>
                    •     @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
                    •   </code>
                    • </pre>

                    • <P>
                    •   
                    •    <code>
                    •     ViewControllerB
                    •   </code>
                    •    我们在上面打电话给<code>
                    •     delegate
                    •   </code>
                    •    当我们弹出视图控制器时。
                    • </p>
                    •  <pre>
                    •   <code>
                    •     NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
                    • [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];

                    •   </code>
                    • </pre>

                    • <P>
                    •   就是这样
                    •    <code>
                    •     ViewControllerB
                    •   </code>
                    •   。现在进来
                    •    <code>
                    •     ViewControllerA.h
                    •   </code>
                    •   告诉我
                    •    <code>
                    •     ViewControllerA
                    •   </code>
                    •    进口
                    •    <code>
                    •     ViewControllerB
                    •   </code>
                    •    并符合其协议。
                    • </p>
                    •  <pre>
                    •   <code>
                    •     #import "ViewControllerB.h"
                  1. @interface ViewControllerA : UIViewController

                  1.     </code>
                  1.   </pre>
                  1. </LI>
                  1. <LI>
                  1.   <P>
                  1.     
                  1.      <code>
                  1.       ViewControllerA.m
                  1.     </code>
                  1.      从我们的协议实现以下方法
                  1.   </p>
                  1.    <pre>
                  1.     <code>
                  1.       - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
                  1. {
                    NSLog(@”This was returned from ViewControllerB %@”,item);
                    }

                  1.     </code>
                  1.   </pre>
                  1. </LI>
                  1. <LI>
                  1.   <P>
                  1.     在推之前
                  1.      <code>
                  1.       viewControllerB
                  1.     </code>
                  1.      我们需要告诉导航堆栈
                  1.      <code>
                  1.       ViewControllerB
                  1.     </code>
                  1.      
                  1.      <code>
                  1.       ViewControllerA
                  1.     </code>
                  1.      是它的代表,否则我们会得到一个错误。
                  1.   </p>
                  1.    <pre>
                  1.     <code>
                  1.       ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
                  1. viewControllerB.delegate = self
                    [[self navigationController] pushViewController:viewControllerB animated:YES];

                  1.     </code>
                  1.   </pre>
                  1. </LI>
                  1. </醇>




                    参考





                    1. 使用委派与其他视图控制器通信

                      在里面

                      View Controller编程指南




                    2. 委托模式


                    3. </醇>



                      NSNotification中心
                      </强>

                    1. 这是传递数据的另一种方式。




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

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

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

                    1. </code>



                    1. 将数据从一个类传递回另一个类
                      </强>
                      (类可以是任何控制器,网络/会话管理器,UIView子类或任何其他类)




                      块是匿名函数。



                      此示例从中传递数据

                      控制器B.
                      </强>


                      控制器A.
                      </强>




                      定义一个块
                      </强>




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

                    1. </code>



                    1. 添加块处理程序(侦听器)
                      </强>

                    1. 您需要一个值的位置(例如,您需要在ControllerA中使用API​​响应,或者您需要在A上使用ContorllerB数据)




                      // in ContollerA.m

                      • (void)viewDidLoad {
                        [super viewDidLoad];
                        __unsafe_unretained typeof(self) weakSelf = self;
                        self.selectedVoucherBlock = ^(NSString *voucher) {

                      •   weakSelf->someLabel.text = voucher;
                      • };
                        }




                    1. 转到控制器B.
                    1. </强>



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




                    1. 火块
                    1. </强>



                    1. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: 
                    1. (NSIndexPath )indexPath {
                      NSString
                      voucher = vouchersArray[indexPath.row];
                      if (sourceVC.selectVoucherBlock) {

                    1.   sourceVC.selectVoucherBlock(voucher);
                    1. }
                      [self.navigationController popToViewController:sourceVC animated:YES];
                      }




                    1. 块的另一个工作示例


          2. 21# 不见你 | 2019-08-31 10-32



            在我的例子中,我使用了一个单例类,它可以作为一个全局对象,允许从应用程序的几乎所有位置访问数据。首先是建立一个单例类。请参阅页面,“

            我的Objective-C单身人物应该是什么样的?


            而我所做的使全局可访问的对象只是将其导入

            appName_Prefix.pch

            这是为了在每个类中应用import语句。
            要访问此对象并使用,我只需实现类方法即可返回包含其自身变量的共享实例


          登录 后才能参与评论