【问题标题】:3D Touch UIapplicationShortcut doesn't work when app is closed应用程序关闭时 3D Touch UIapplicationShortcut 不起作用
【发布时间】:2015-10-13 12:37:22
【问题描述】:

您好,提前致谢。

我编写了一个应用程序,它使用 3D 触摸在主屏幕上使用新的 UIApplicationShortcut。一旦应用成为应用,快捷方式就可以使用,但如果应用关闭,则快捷方式在主屏幕上不起作用。

当应用程序关闭时,快捷方式会启动应用程序,但快捷方式不起作用,只会启动应用程序。

这是我用于快捷方式的两种方法。

- (void)setupViewControllers {
    // setup the navigation stack

    CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
    if (iOSDeviceScreenSize.height == 480)
    {
        _navigationController = (UINavigationController *)self.window.rootViewController;

        // iPhone 5 and iPod Touch 5th generation: 4 inch screen
        // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
        UIStoryboard *iPhone4Storyboard = [UIStoryboard storyboardWithName:@"Main4s" bundle:nil];

        UIViewController *initialViewController = [iPhone4Storyboard instantiateInitialViewController];
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

        self.window.rootViewController  = initialViewController;

        self.myViewController = (ViewController *)_navigationController.topViewController;
        self.myViewController.managedObjectContext = self.managedObjectContext;

        [self.window makeKeyAndVisible];
    }

    if (iOSDeviceScreenSize.height == 568)
    {
        _navigationController = (UINavigationController *)self.window.rootViewController;

        // iPhone 5 and iPod Touch 5th generation: 4 inch screen
        // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
        UIStoryboard *iPhone4Storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

        UIViewController *initialViewController = [iPhone4Storyboard instantiateInitialViewController];
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

        self.window.rootViewController  = initialViewController;

        self.myViewController = (ViewController *)_navigationController.topViewController;
        self.myViewController.managedObjectContext = self.managedObjectContext;

        [self.window makeKeyAndVisible];
    }

    if (self.myViewController){NSLog(@"myViewController is not nil, setupViewControllers");}
    else
    {
        NSLog(@"myViewController is nil, setupViewControllers");//breakpoint inserted here...
    }
}

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {

    [self setupViewControllers];

    // react to shortcut item selections
    NSLog(@"A shortcut item was pressed. It was %@.", shortcutItem.localizedTitle);
    if([shortcutItem.localizedTitle isEqualToString:@"Scan Tag"])
    {
        [self.myViewController toggleScanningTapped:nil];
    }
    if([shortcutItem.localizedTitle isEqualToString:@"Enter Tag"])
    {
        [self.myViewController manualEntry];
    }
    if([shortcutItem.localizedTitle isEqualToString:@"Search for a Tag"]){
        [self.myViewController SearchSwitch];
        [self.myViewController toggleScanningTapped:nil];
    }
    if([shortcutItem.localizedTitle isEqualToString:@"Just Scan & Copy"]){
        [self.myViewController justCopy];
    }

    if (self.myViewController){NSLog(@"myViewController is not nil, performActionForShortcutItem");}
    else
    {
        NSLog(@"myViewController is nil, performActionForShortcutItem");
    }
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    [self setupViewControllers];

    NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
    if (url != nil && [url isFileURL]) {
        [self.myViewController handleOpenURL:url];
    }

    if (self.myViewController){NSLog(@"myViewController is not nil, didFinishLaunchingWithOptions");}
    else{NSLog(@"myViewController is nil, didFinishLaunchingWithOptions");}

    return YES;
}

这里是 plist 条目...

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>com.PALIANTech.SUNYScanner.static1</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Scan Tag</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Add tag to DB</string>
        <key>UIApplicationShortcutItemIconFile</key>
        <string>barcode.png</string>
    </dict>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>com.PALIANTech.SUNYScanner.static2</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Enter Tag</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Manually add tag to DB</string>
        <key>UIApplicationShortcutItemIconFile</key>
        <string>ManualEntry.png</string>
    </dict>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>com.PALIANTech.SUNYScanner.static3</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Search for a Tag</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Scan a tag to search for</string>
        <key>UIApplicationShortcutItemIconFile</key>
        <string>search.png</string>
    </dict>
</array>
</plist>

任何帮助或建议将不胜感激。

【问题讨论】:

    标签: ios objective-c iphone ios9 3dtouch


    【解决方案1】:

    原因是当您的应用程序重新启动时self.myViewController 在您检查performActionForShortcutItem 和didFinishLaunchingWithOptions 中的快捷方式时仍然是nil。所以什么都没有发生。

    要解决此问题,您必须实例化 myViewController 并在通过快捷方式打开应用时将其添加到导航堆栈中。

    编辑

    这是一个有效的(精简版)版本:

    AppDelegate

    @interface AppDelegate ()
    @property ViewController *viewController;
    @end
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        [self setupViewControllers];
    
        return YES;
    }
    
    - (void)setupViewControllers {
        self.viewController = [[ViewController alloc] init];
        self.viewController.view.backgroundColor = [UIColor lightGrayColor];
        self.viewController.label.text = @"Normal Launch";
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    
        self.window.rootViewController  = navigationController;
        [self.window makeKeyAndVisible];
    }
    
    - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
        [self setupViewControllers];
    
        if([shortcutItem.localizedTitle isEqualToString:@"Scan Tag"]) {
            self.viewController.label.text = @"Shortcut: Scan Tag";
        }
        if([shortcutItem.localizedTitle isEqualToString:@"Enter Tag"]) {
            self.viewController.label.text = @"Shortcut: Enter Tag";
        }
        if([shortcutItem.localizedTitle isEqualToString:@"Search for a Tag"]) {
            self.viewController.label.text = @"Shortcut: Search Tag";
        }
        if([shortcutItem.localizedTitle isEqualToString:@"Just Scan & Copy"]) {
            self.viewController.label.text = @"Shortcut: Scan & Copy Tag";
        }
    }
    
    @end
    

    ViewController 类是一个普通的UIViewController 子类,它只有一个用于演示目的的标签。

    我已经使用后台应用程序测试了快捷方式,并且该应用程序已完全从内存中删除。两者都按预期工作。

    更新

    如果您使用情节提要中的 ViewController,您必须像这样初始化它:

    - (void)setupViewControllers {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        self.viewController = (ViewController *)[storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
        ...
    }
    

    不要忘记在情节提要中设置 ViewController 的标识符:

    【讨论】:

    • 感谢您的回复。我编辑了上面的代码,希望能反映你的答案,但还没有得到它。
    • 您可以发布您的更改吗?
    • 我认为问题在于myViewController 在performActionForShortcutItem: 中仍然是nil。当应用程序通过快捷方式启动时,它首先调用performActionForShortcutItem:。我的建议是您从didFinishLaunchingWithOptions 中删除所有快捷方式代码,并将视图控制器初始化代码移动到一个额外的方法,而不是您可以从performActionForShortcutItem: 和didFinishLaunchingWithOptions 调用
    • 感谢您在这方面与我合作。当我将导航堆栈代码移动到 setupViewControllers 时,从 didFinishLaunchingOptions 中删除快捷方式代码,并从 didFinishLaunchingWithOptions 和 performActionForShortcutItem 调用它...当应用程序在后台或应用程序未打开时,快捷方式不起作用。
    • 你是否在'performAction'中设置了断点来查看你的ViewController是否为nil?
    猜你喜欢
    • 1970-01-01
    • 2017-06-23
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多