Page Based “reloadRootControllersWithNames:” on la

2019-01-18 13:03发布

- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
    [WKInterfaceController reloadRootControllersWithNames:@[@"pageOne", @"pageTwo"] contexts:nil];
}

Following Apple's guidelines

Call this method to reload the pages in your app’s page-based interface. At launch time, you use this method to customize the set of pages you want displayed.

at launch time, only results in a loop. With each reload calling awakeWithContext or will Activate or init again and again.

Is there a better way to go about reloading the Page-Based app on launch with a loop occurring?

4条回答
三岁会撩人
2楼-- · 2019-01-18 13:12

Really easy to solve, and does not require Multiple Page Controllers -- Just use once

Create a class variable (not an instance variable) and use that as your flag to ensure that your call to reloadRootControllers is only ever called once.

static NSString* hasLaunchedIfNotNullString = NULL;

- (void)awakeWithContext:(id)context
{
    if(hasLaunchedIfNotNullString == NULL)
    {
        //START Code which gets executed once
        hasLaunchedIfNotNullString = @"";

        ...
        [WKInterfaceController reloadRootControllersWithNames:YOUR_ARRAY contexts:CONTEXTS];
        // END code which gets executed once
    }
}
查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-18 13:18

This is a common problem with WatchKit apps since we no longer have a UIApplicationDelegate to handle such set up. A good approach would be to structure your code as follows:

  • MainInterfaceController (the main link in storyboard points here)
  • PageOneInterfaceController - your first interface to display in the page set
  • PageTwoInterfaceController - your second interface in the page set

The MainInterfaceController will never actually get displayed. You will always launch into a different set of interface controllers depending on the cached state of the companion iOS App in MainInterfaceController.awakeWithContent(). This way, you use the MainInterfaceController in a similar manner that we use the UIApplicationDelegate in iOS to set up the window and root view controller.

I have used this approach in an app that had many different page sets to choose from and it worked very well.

查看更多
聊天终结者
4楼-- · 2019-01-18 13:25

That is why awakeWithContext: exists. The first time your app is launched, the initial controller is passed nil as context. But if you reloadRootControllersWithNames:contexts:, you have an opportunity to pass a custom context instance and thus distinguish the launch mode.

查看更多
手持菜刀,她持情操
5楼-- · 2019-01-18 13:35

calling WKInterfaceController.reloadRootControllers causes the awake function to be called a second time. This is the solution I use - it is straight forward, compact, and eliminates the recursive loop. This example has two page based views called mainControls and nowPlaying that are configured with contexts. Note the key thing here is to configure the mainControls view controller with an empty string context then that context is checked and returns if it is being called again due to the WKInterfaceController.reloadRootControllers statement that configured the context to "". Note the first time awake runs the context for the main view controller will be nil. Also note the second context is an implementation detail specific to my implementation - this could be any object that you want to pass to the second view controller.

override func awake(withContext context: Any?) {
    super.awake(withContext: context)
    if let _ = context as? String {
        print("already configured!")
        return
    }
    print("configuring...")
    WKInterfaceController.reloadRootControllers(withNames: ["mainControls", "nowPlaying"], contexts: ["", interaction])
}
查看更多
登录 后发表回答