像上圖那樣,按壓圖標 彈出菜單。這是應用最多的場景。那麼如何實現呢?有兩種方法:git
在info.plist添加以下鍵值對,每個Item表明一個標籤按鈕,你能夠添加標題,副標題,可使用系統圖標,也可使用你本身的圖片資源做爲圖標,只需添加你的圖片名稱便可。下面列舉經常使用的鍵值對:github
/* 經常使用鍵值對 UIApplicationShortcutItemTitle 標題 UIApplicationShortcutItemType 類型能夠設置標識符 UIApplicationShortcutItemIconType 圖標類型,可設置系統圖標樣式 UIApplicationShortcutItemSubtitle 副標題 UIApplicationShortcutItemUserInfo 可存放一個字典,經過這個傳值 */
下面列舉系統支持的圖標類型,根據你的需求來獲取吧。數組
//建立圖標3DTouch 菜單 - (void)codeAddItems{ //系統風格的icon UIApplicationShortcutIcon *share = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare]; //使用自定義圖標 UIApplicationShortcutIcon *saoyisao = [UIApplicationShortcutIcon iconWithTemplateImageName:@"erweima"]; //建立快捷選項 type 標識符 UIApplicationShortcutItem * item1 = [[UIApplicationShortcutItem alloc]initWithType:@"com.occode.app.share" localizedTitle:@"分享" localizedSubtitle:@"分享副標題" icon:share userInfo:nil]; UIApplicationShortcutItem * item2 = [[UIApplicationShortcutItem alloc]initWithType:@"com.mycompany.app.saoyisao" localizedTitle:@"掃一掃" localizedSubtitle:@"掃一掃副標題" icon:saoyisao userInfo:nil]; //添加到快捷選項數組 [UIApplication sharedApplication].shortcutItems = @[item1,item2]; }
運行效果:瀏覽器
動態標籤不能覆蓋靜態標籤,但能夠追加,最多支持四個標籤。微信
點擊後,咱們能夠從launchOptions中捕捉到UIApplicationShortcutItem,從而根據其類型來處理咱們想要的結果:app
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;ide
捕捉UIApplicationShortcutItem,此時咱們須要return NO而不是YES;函數
//若是是從快捷選項標籤啓動app,則根據不一樣標識執行不一樣操做,而後返回NO UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey]; if (shortcutItem) { //根據Item的類型來進一步處理 [self showForItem:shortcutItem]; return NO; }
須要實現下面這個函數:測試
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;字體
具體實現以下:
//若是app在後臺,經過快捷選項標籤進入app,則調用該方法 - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler { //判斷先前咱們設置的快捷選項標籤惟一標識,根據不一樣標識執行不一樣操做 [self showForItem:shortcutItem]; if (completionHandler) { completionHandler(YES); } }
首先來看看微信的效果圖:
//判斷是否支持3DTouch - (BOOL)isValidForceTouch{ return self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable; }
//給這個cell註冊3DTouch預覽功能 [self registerForPreviewingWithDelegate:self sourceView:cell];
// peek 預覽 - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{ //按壓的行 NSIndexPath * indexPath = [_tableView indexPathForCell:(UITableViewCell *)[previewingContext sourceView]]; //預覽界面 ShowViewController * showVC = (ShowViewController *)[self vcForSBID:kShowVCId]; showVC.title = @"我是按進來的"; showVC.text = [self selectedTextForRow:indexPath.row]; //臨時顯示自定義的導航 [showVC showTitle]; return showVC; }
看下運行效果:
//pop 進入 - (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{ ShowViewController * showVC = (ShowViewController *)viewControllerToCommit; //隱藏咱們臨時的導航,由於進入後有真正的導航 [showVC hideTitle]; [self showViewController:viewControllerToCommit sender:self]; }
運行效果圖:
先來看看微信的效果圖:
咱們只須要在預覽控制器裏實現以下方法,返回一個UIPreviewActionItem的數組:
//peek 時上滑出現的菜單 - (NSArray<id<UIPreviewActionItem>> *)previewActionItems { // 普通樣式 UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Aciton1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"Aciton1"); }]; //已被選擇的樣式 後面有個對勾 UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Aciton2" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"Aciton2"); }]; //警示樣式(紅色字體) UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Aciton3" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"Aciton3"); }]; NSArray *actions = @[action1,action2,action3]; return actions; }
運行效果圖:
細心地同窗發現,預覽的界面是沒有導航欄的,微信是怎麼實現的呢?我在試了不少方法,發現「在peek是顯示一個自定義的導航欄,pop時隱藏自定義的導航欄」是一個可行的辦法(若是哪位同窗知道更好的辦法能夠聯繫本人!!)。
有時候咱們只想按壓某一個區域來預覽,而不是整個cell,也許是cell上的label,或view上的某一個區塊,這時候咱們能夠改變顯示的上下文視圖的Rect來改變:
previewingContext.sourceRect = CGRectMake(0, 0, 300, 20);
預覽視圖的大小是能夠改變的,若是你按壓的是一個圖片,pop出圖片瀏覽器,顯然效果不是那麼理想,咱們能夠根據圖片的大小來設置預覽視圖的大小:
// peek 預覽 - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{ //預覽界面 PhotoViewController * pvc = [[PhotoViewController alloc]init]; pvc.image = _imageView.image; //設置預覽視圖的比例 能夠看出 預覽視圖的寬高比例 圖片的比例是一致的 pvc.preferredContentSize = CGSizeMake(_imageView.image.size.width, _imageView.image.size.height); return pvc; }
預覽視圖比例演示效果以下:
經過touchesBegan、touchesMoved等方法來捕獲,獲取force值:
//按住移動or壓力值改變時的回調 -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSArray *arrayTouch = [touches allObjects]; UITouch *touch = (UITouch *)[arrayTouch lastObject]; NSLog(@"move壓力 = %f",touch.force); //label顯示壓力值 _textLabel.text = [NSString stringWithFormat:@"壓力%f",touch.force]; self.view.backgroundColor = [self colorForForce:touch.force]; }
經測試發現壓力的範圍是0.06666...~6.6666...,須要注意的是 這裏的force 」壓力「值 並非以牛頓爲單位的物理上的力,而表明的是一個相對的參考系 咱們經過0.666... ~ 6.666... 來模擬壓力的小和大。例如:我吧force值和顏色對應起來,按得越重,背景顏色就越黑。
效果以下:
3DTouch用處還未被徹底挖掘,但願iOS Coder能夠用它開發出更有意思的產品和功能。
github: