在重新加载UIView之前,更新标签文本并不起作用

时间:2014-10-01 18:15:58

标签: ios objective-c uiview xib

我正在努力解决一个我根本不理解的问题。以下是以下情形:

  1. 我尝试在iOS中创建一个多视图向导。经过深思熟虑后,我决定采用一种可能不太理想的方法,但会帮助我保持代码清洁。我不想链接十个视图控制器并手动管理。
  2. 该向导有一个视图控制器。在开始时,它会将一定量的UIView加载到视图中,并允许我向左和向右滚动。代码如下。
  3. UIViews是在界面构建器中创建的,我有一个包含所有视图的XIB文件。
  4. 每个UIView都有更多的IBOutlets(例如标签),它们连接到文件所有者,在本例中是向导视图控制器。
  5. 除了加载的UIViews上的标签不会更新之外,这一切都非常有效。这是问题所在:

    1. 我调用向导,然后加载所有UIViews和Outlets
    2. 我跳过向导。
    3. 但问题出现了:

      • 示例:
      • 第2步有一个按钮来调用地址簿(可以正常工作)
      • 地址簿打开,返回一个对象(有效)
      • 但我在UIView上的标签"第2步"在分配值时不会更新。
    4. 只有在我从向导中删除此UIView并将其添加回来之后,才有效。在我看来,UIView正确加载,但任何后续的改变他们的网点都不起作用。

      顺便说一句,我确认标签以及按钮和一切都可能已连接。当它作为XIB的一部分加载时,我无法更新标签,并且在初始加载后值会发生变化。

      代码:

      向导加载UIViews:

      -(void)configureWizard
      {
          self.showsHorizontalScrollIndicator = NO;
          self.showsVerticalScrollIndicator = NO;
          self.scrollEnabled = NO;
          self.contentSize = CGSizeMake(CGRectGetWidth(self.frame) * [wizardDelegate numberOfSteps], CGRectGetHeight(self.frame));
          self.delegate = self;
      }
      
      -(void)loadWizard
      {
          [self configureWizard];
          [self updateNavButtonsIfNecessary];
          currentIndex = 0;
          for (int i = 0; i<[wizardDelegate numberOfSteps]; i++)
          {
              [self loadWizardStepAtIndex:i];
          }
      }
      
      - (void)loadWizardStepAtIndex:(int)index {
          CGRect frame = self.frame;
          frame.origin.x = CGRectGetWidth(frame) * index;
          frame.origin.y = 0;
          UIView *view = [wizardDelegate viewForStepAtIndex:index];
          view.frame = frame;
      
          [self addSubview:view];
      }
      

      向导主视图Controller.h(文件所有者)

      @property (strong, nonatomic) IBOutlet UIView *memberwizard_1;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_2;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_3;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_4;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_5;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_6;
      @property (strong, nonatomic) IBOutlet UIView *memberwizard_7;
      
      
      @property (strong, nonatomic) IBOutlet UIButton *wizard2_lookupExistingContact;
      @property (strong, nonatomic) IBOutlet UILabel *wizard2_nameLabel;
      

      向导主视图Controller.m(文件所有者)

      -(UIView *)viewForStepAtIndex:(int)index
      {
          [[[NSBundle mainBundle]loadNibNamed:@"wizard_newMember" owner:self options:nil] lastObject];;
      
          switch (index) {
              case 0:
                  return self.memberwizard_1;
                  break;
              case 1:
                  return self.memberwizard_2;
                  break;
              case 2:
                  return self.memberwizard_3;
                  break;
              case 3:
                  return self.memberwizard_4;
                  break;
              case 4:
                  return self.memberwizard_5;
                  break;
              case 5:
                  return self.memberwizard_6;
                  break;
              case 6:
                  return self.memberwizard_7;
                  break;
      
              default:
                  return self.memberwizard_1;
          }
      }
      

      地址簿的返回功能

      -(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
      {
          [self displayPersonRecord:person];
          [self dismissViewControllerAnimated:YES completion:nil];
      }
      

      尝试更新第二个UIView上的标签(这是问题发生的地方 - 它不起作用)。

      -(void) displayPersonRecord:(ABRecordRef)person
      {
          NSString *firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
          NSString *lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
          NSLog(@"Name is %@", [NSString stringWithFormat:@"%@ %@", firstName, lastName]);
          self.wizard2_nameLabel.text = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
          [self.wizardDelegate refresh:self.memberwizard_2]; //if called, the current view will be removed and re-added - then the label gets updated.
      }
      

      但正如我所提到的,如果我重新加载视图,那么它的工作原理(见截图)

      重新载入方法重要说明:这是一个讨厌的代码,并没有在生产中使用,它只是一个测试,看看视图的重新加载是否有帮助。

      -(void)refresh:(UIView *) oldView
      {
          [oldView removeFromSuperview];
          CGRect frame = self.frame;
          frame.origin.x = CGRectGetWidth(frame) * currentIndex;
          frame.origin.y = 0;
          //UIView *view = [wizardDelegate viewForStepAtIndex:currentIndex];
          oldView.frame = frame;
          [self addSubview:oldView];
      }
      

      如果此时我从向导中删除了self.memberwizard_2视图并将其添加回一切正常但它不会立即生效。这可能与我发起UIViews的方式有关吗?顺便说一句,最后一段中的NSLog也可以显示联系人的姓名。

      如果有人知道更简单的方法来处理向导让我知道:) PageViewControllers是痛苦的,因为我需要将一个对象从一个屏幕切换到另一个屏幕,但需要在每个屏幕上显示不同的动作。

      非常感谢并为代码混乱道歉,我尽量让它尽可能清楚,但也许不是。

      Step 1 - skip to memberwizard_2 view

      Step 2 - select contact

      Step 3 - label doesnt get updated on return

      Step 4 - it works after reloading the view

1 个答案:

答案 0 :(得分:0)

在这里,我认为它出了问题。对于每个&#34; WizardStep&#34;,您调用加载NIB的viewForStepAtIndex并返回相关视图。然后将其添加为子视图。但是当您处理下一个WizardStep时,NIB再次加载 ,这将创建其所有对象的新实例,并将所有Outlets和Actions重新连接到新加载的对象。因此,您刚刚添加的子视图(以及显示的视图)不再由您的商店指向。因此,当您更新标签时,它不会更新屏幕上的标签,而是根本不在层次结构中的视图上的完全不同的标签。

因此,我会修改您的代码,以便loadNibNamed:方法只运行一次。