页面视图控制器更新视图控制器?

Page View Controller update view controllers ?

我有一个页面视图控制器,每次用户滑动时我都使用此方法来检测转换是否完成。

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed

现在我在页面视图控制器中显示了 5 个视图控制器,并且每个视图控制器都有一个 UILabel他们。使用上面的 方法 来检测成功的转换,我想在每次转换完成时 使用来自页面视图控制器 class 的数据更新 UILabels。

因此,每次用户滑动时,我都希望 5 个视图控制器上的 UILabel 使用我的页面视图控制器 class 中的新值进行更新。

最好的方法是什么(定期更新来自不同 class 的 strings/calling 方法)?我环顾四周,找不到任何关于这个的东西?!非常感谢任何帮助,谢谢。

您可以通过两种方式完成,

  1. 如果您以编程方式创建 UILabel 以使所有子视图控制器继承自具有 UILabel 的视图控制器,那么代码将是这样的

    @interface ViewControllerWithLabel : UIViewController 
    
    @property (strong, nonatomic) UILabel *someLabel;
    
    @end
    

    然后页面中的所有控制器都将继承自此

    @interface ViewControllerPage1: ViewControllerWithLabel
    

    ...

    @interface ViewControllerPage2: ViewControllerWithLabel
    

    ...

    @interface ViewControllerPage3: ViewControllerWithLabel
    

    ...

    @interface ViewControllerPage4: ViewControllerWithLabel
    

    ...

    @interface ViewControllerPage5: ViewControllerWithLabel
    

在你的

    - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
    {
        for(ViewControllerWithLabel *changeView in pageViewController.viewControllers)
        {
             changeView.someLabel = @"Some Text";
        }
     }
  1. 第二种方式,如果你使用 Storyboard 和 IBOutlet,你将必须检查每种类型 ViewController 并按如下方式设置标签

     - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
    {
        for(UIViewController *changeView in pageViewController.viewControllers)
        {
            if ([changeView isKindOfClass:[ViewControllerPage1 class]]
            {
                  ViewControllerPage1* temp = (ViewControllerPage1*)changeView;
                 temp.labelName.text = @"Some Text";
            }
            else if ([changeView isKindOfClass:[ViewControllerPage2 class]]
            {
                  ViewControllerPage2* temp = (ViewControllerPage2*)changeView;
                 temp.labelName.text = @"Some Text";
            }   
            else if ([changeView isKindOfClass:[ViewControllerPage3 class]]
            {
                  ViewControllerPage3* temp = (ViewControllerPage3*)changeView;
                 temp.labelName.text = @"Some Text";
            }
            else if ([changeView isKindOfClass:[ViewControllerPage4 class]]
            {
                  ViewControllerPage4* temp = (ViewControllerPage4*)changeView;
                 temp.labelName.text = @"Some Text";
            }
            else if ([changeView isKindOfClass:[ViewControllerPage5 class]]
            {
                  ViewControllerPage5* temp = (ViewControllerPage5*)changeView;
                 temp.labelName.text = @"Some Text";
            }
        }
     }
    

So every time the user swipes I want the UILabels on the 5 view controllers to be updated with new values from my page view controller class.

你不能,原因很简单 "the 5 view controllers" 不存在。这不是 UIPageViewController 的工作方式。它一次只有 一个 个子视图控制器 — 当前页面。

因此,当用户滚动到特定视图控制器(页面)时,您可以更新该视图控制器的标签。在那一刻,你将不得不重新创建和提供视图控制器,你可以用标签的适当值来配置它。否则,您只需要坐在那里,存储标签 具有的值,直到那一刻到来。

我发现最好的方法是通过 NSNotifications。我在我想要更新的每个视图控制器 class 中创建一个观察者,然后我只需在主 class 中调用通知,然后视图控制器调用其中的一个方法!如此简单干净!

在您要更新的 class 中添加:

 [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateLabel:)
                                                 name:@"LABELUPDATENOTIFICATION1"
                                               object:nil];

为其创建一个方法:

- (void)updateLabel:(NSNotification*)notification
{
    NSString *updatedText = (NSString*)[notification object];
    [nameLabel setText:updatedText];
}

然后从任何其他 class 调用它,您创建的方法将被调用:

[[NSNotificationCenter defaultCenter] postNotificationName:@"LABELUPDATENOTIFICATION1"object:content1];

我很惊讶从一开始就没有人向我提出这个建议,因为这太简单了,所有其他答案似乎都太复杂了。