蘋果在iPhone6s和iPhone6s Plus中加入了3D Touch技術(shù)茸时,其實Apple Watch的屏幕上很早就用到這一技術(shù)了符隙,并不新穎,由于本人剛買的iPhone6s下硕,所以試玩一下砰左。沒有6S和6SP的小伙伴也不要抱怨,好東西來了:SBShortcutMenuSimulator,能讓模擬器支持HomeScreen Quick Action睡榆。趕緊去嘗試吧~
SBShortcutMenuSimulator
1.編譯:在終端依次輸入下面的命令
git clone https://github.com/DeskConnect/SBShortcutMenuSimulator.git
cd SBShortcutMenuSimulator
make
2.讓SpringBoard支持SBShortcutMenuSimulator
xcrun simctl spawn booted launchctl debug system/com.apple.SpringBoard --environment DYLD_INSERT_LIBRARIES=$PWD/SBShortcutMenuSimulator.dylib
xcrun simctl spawn booted launchctl stop com.apple.SpringBoard
3.預(yù)覽:
echo 'com.apple.mobilecal' | nc 127.0.0.1 8000
注意:'com.apple.mobilecal' 是系統(tǒng)自帶日歷的BundleID萍肆,記得要換成自己的喔~
Home Screen Quick Action
創(chuàng)建Quick Action分為靜態(tài)和動態(tài)兩種方式:動態(tài)就是代碼實現(xiàn),但是程序要運行一次才會有效果胀屿;靜態(tài)就是通過程序的Info.plist文件來設(shè)置塘揣。
動態(tài)實現(xiàn)的代碼如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIApplicationShortcutIcon *addIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd];
UIApplicationShortcutIcon *shareIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
UIApplicationShortcutIcon *searchIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeSearch];
UIApplicationShortcutItem *item0 = [[UIApplicationShortcutItem alloc] initWithType:@"1" localizedTitle:@"添加" localizedSubtitle:nil icon:addIcon userInfo:nil];
UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc] initWithType:@"2" localizedTitle:@"分享" localizedSubtitle:nil icon:shareIcon userInfo:nil];
UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc] initWithType:@"3" localizedTitle:@"搜索" localizedSubtitle:nil icon:searchIcon userInfo:nil];
NSArray *itemArray = [NSArray arrayWithObjects:item0,item1,item2, nil];
[[UIApplication sharedApplication] setShortcutItems:itemArray];
return YES;
}
響應(yīng)回調(diào):
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
if ([shortcutItem.localizedTitle isEqualToString:@"1"]) {
NSLog(@"添加");
}else if ([shortcutItem.localizedTitle isEqualToString:@"2"]){
NSLog(@"分享");
}else if([shortcutItem.localizedTitle isEqualToString:@"3"]){
NSLog(@"搜索");
}
}
特別注意:
**1.每個APP最大支持4個Action Item;
2.靜態(tài)動態(tài)同時設(shè)置的時候宿崭,不會覆蓋亲铡;
**
UIKit Peek & Pop
短時間按壓屏幕可以實現(xiàn)預(yù)覽,這就是peek葡兑,再用力按壓奖蔓,直接進(jìn)到另一個頁面,就是Pop了讹堤。要實現(xiàn)Peek和Pop功能吆鹤,首先要判斷設(shè)備是否支持3D Touch功能,然后遵守UIViewControllerPreviewingDelegate洲守,并實現(xiàn)它僅有的兩個方法:
監(jiān)測3D Touch:
我們可以在viewWillAppear方法里檢測:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
NSLog(@"3D Touch 可用");
}else if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityUnavailable){
NSLog(@"3D Touch 不可用");
}else{
NSLog(@"3D Touch 未檢測");
}
}
如果程序內(nèi)修改了3D Touch設(shè)置疑务,我們通過traitCollectionDidChange來檢測:
//生命周期內(nèi)可以通過這個方法重新檢測3D Touch功能
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
//功能可用的情況下進(jìn)行注冊
[self registerForPreviewingWithDelegate:self sourceView:self.tableView];
NSLog(@"已注冊");
}else{
NSLog(@"沒注冊");
}
}
實現(xiàn)UIViewControllerPreviewingDelegate的代理方法:
#pragma mark - viewcontrollerPrewingdelegate
//Peek 代理方法:
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
//防止重復(fù)彈出
if ([self.presentationController isKindOfClass:[PeekViewController class]]) {
return nil;
}else{
//找到正在按壓的cell,從而著重顯示梗醇,
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (!cell) {
return nil;
}
previewingContext.sourceRect = cell.frame;
PeekViewController *peekVC = [[PeekViewController alloc] initWithNibName:@"PeekViewController" bundle:nil];
peekVC.preferredContentSize = CGSizeMake(0, 0);
return peekVC;
}
}
//Pop 代理方法:
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
{
PeekViewController *peekVC = [[PeekViewController alloc] initWithNibName:@"PeekViewController" bundle:nil];
peekVC.sendData = @"from POP";
[self presentViewController:peekVC animated:YES completion:nil];
}
你可能見過類似的效果:
那么底下的這些選項又是怎么實現(xiàn)的呢知允?這個呢,需要在目標(biāo)控制器里設(shè)置叙谨,也就是說温鸽,如果你的A控制器實現(xiàn)了上面的代理方法,然后想跳到B控制器手负,那么這些選項的設(shè)置就要在B控制器里通過UIPreviewAction來設(shè)置涤垫。
//初始化preViewActionsItems
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
UIPreviewAction *action0 = [UIPreviewAction actionWithTitle:@"取消關(guān)注" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"取消關(guān)注");
}];
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"刪除" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"刪除");
}];
NSArray *previewActionItemsArray = @[action0,action1];
return previewActionItemsArray;
}
OK~終于大功告成了。