大年初一,在家無事
甚是無聊,撰文一篇
自蘋果在2015年發(fā)布3DTouch功能以來
iPhone 6s之后的機(jī)型全都匹配了3DTouch功能
說來慚愧
還沒自己寫過3DTouch相關(guān)的代碼
于是研究了一波
我的研究大概包括以下三個方面:
- 在應(yīng)用icon上呼出3DTouch菜單
- 在程序內(nèi)部的Peek和Pop
- Widget開發(fā)
一: 在應(yīng)用icon上呼出3DTouch菜單
搞出這種效果有兩種方式:
- 在plist里面添加字段
- 在didFinishLaunchingWithOptions中用代碼添加
第1種方式 : 在plist里面添加字段:
UIApplicationShortcutItemTitle : 必有用作按鈕的標(biāo)題
UIApplicationShortcutItemSubtitle : 非必有,用作按鈕子標(biāo)題
UIApplicationShortcutItemType : 必有,根據(jù)這個字段來判斷點了哪個按鈕
UIApplicationShortcutItemIconFile : 非必有, 圖片的名字(自定義)
UIApplicationShortcutItemIconType :非必有, 圖片的類型(系統(tǒng)提供)
UIApplicationShortcutItemUserInfo : 非必有,設(shè)置用戶信息,是一個字典類型,可以用來傳值
說明 :
少了任意必有項,這個按鈕都不顯示
UIApplicationShortcutItemIconFile和UIApplicationShortcutItemIconType必有其一
最多創(chuàng)建四個按鈕
UIApplicationShortcutItemIconType的類型 :
// Override point for customization after application launch.
/**
*
typedef NS_ENUM(NSInteger, UIApplicationShortcutIconType) {
UIApplicationShortcutIconTypeCompose,
UIApplicationShortcutIconTypePlay,
UIApplicationShortcutIconTypePause,
UIApplicationShortcutIconTypeAdd,
UIApplicationShortcutIconTypeLocation,
UIApplicationShortcutIconTypeSearch,
UIApplicationShortcutIconTypeShare,
UIApplicationShortcutIconTypeProhibit NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeContact NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeHome NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeMarkLocation NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeFavorite NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeLove NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeCloud NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeInvitation NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeConfirmation NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeMail NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeMessage NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeDate NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeTime NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeCapturePhoto NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeCaptureVideo NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeTask NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeTaskCompleted NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeAlarm NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeBookmark NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeShuffle NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeAudio NS_ENUM_AVAILABLE_IOS(9_1),
UIApplicationShortcutIconTypeUpdate NS_ENUM_AVAILABLE_IOS(9_1)
} NS_ENUM_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED;
*/
第2種方式 : 在didFinishLaunchingWithOptions中用代碼添加
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//自定義3DTouch按鈕
UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:@"4" localizedTitle:@"自定義標(biāo)題1" localizedSubtitle:@"子標(biāo)題4" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeMail] userInfo:nil];
UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:@"5" localizedTitle:@"自定義標(biāo)題2" localizedSubtitle:@"子標(biāo)題5" icon:[UIApplicationShortcutIcon iconWithTemplateImageName:@"icon"] userInfo:nil];
[UIApplication sharedApplication].shortcutItems = @[item1,item2];
return YES;
}
item1是用系統(tǒng)提供的圖片
item2是用自定義圖片
很簡單
然后就是按鈕的監(jiān)聽:
//點擊按鈕進(jìn)入
- (void)application:(UIApplication *)application performActionForShortcutItem:(nonnull UIApplicationShortcutItem *)shortcutItem completionHandler:(nonnull void (^)(BOOL))completionHandler {
if ([shortcutItem.type isEqualToString:@"1"]) {
//相應(yīng)的處理
}else if ([shortcutItem.type isEqualToString:@"2"]) {
//相應(yīng)的處理
}else {
//相應(yīng)的處理
}
}
二: 在程序內(nèi)部的Peek和Pop
大多數(shù)用在tableView上
先看效果圖:
要實現(xiàn)這個效果
得先在TableViewController里面給cell注冊一下
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
cell.textLabel.text = self.dataArray[indexPath.row];
//想要peek 需要注冊一下
[self registerForPreviewingWithDelegate:self sourceView:cell];
return cell;
}
然后遵循UIViewControllerPreviewingDelegate協(xié)議
實現(xiàn)這個方法
返回peek的的控制器
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
//location 是以cell為坐標(biāo)系的坐標(biāo)
//轉(zhuǎn)換成以tableview為坐標(biāo)系的坐標(biāo)
CGPoint point = [self.tableView convertPoint:location fromView:[previewingContext sourceView]];
//這樣就可以取到我點了第幾行cell
NSIndexPath *index = [self.tableView indexPathForRowAtPoint:point];
return [[WebViewController alloc]init];
}
當(dāng)再用力按的時候,就把這個控制器pop進(jìn)來
//pop
//使勁一按 就push
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
//viewControllerToCommit 上個方法返回的vc
[self.navigationController pushViewController:viewControllerToCommit animated:NO];
}
如果想添加操作按鈕
需要在將要彈出的控制器添加這個方法 :
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
UIPreviewAction *item1 = [UIPreviewAction actionWithTitle:@"贊" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"點贊");
}];
UIPreviewAction *item2 = [UIPreviewAction actionWithTitle:@"踩" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"點踩");
}];
UIPreviewAction *item3 = [UIPreviewAction actionWithTitle:@"X" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"點X");
}];
// UIPreviewActionGroup *group = [UIPreviewActionGroup actionGroupWithTitle:@"組" style:UIPreviewActionStyleDefault actions:@[]];
return @[item1,item2,item3];
}
還有值得說的一點就是UITouch對象添加了force
是一個記錄按壓力量的變量
取值是0~6.666
我們可以在touchesMoved里面打印一下
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *t =touches.anyObject;
NSLog(@"按壓力量 - %f",t.force);
}
三: Widget開發(fā)
先上效果圖 :
創(chuàng)建Widget
這個時候,你會看到項目目錄里面多了
如果習(xí)慣純代碼開發(fā),可以刪掉storyboard
在控制器里隨便添加點東西
運行就能看到效果了
如果想讓W(xué)idget可以展開
就像這樣:
可以添加以下代碼:
//改為擴(kuò)充模式(添加拓展按鈕)
- (void)viewWillAppear:(BOOL)animated {
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize{
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 105);
}else {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 500);
}
}
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
// Perform any setup necessary in order to update the view.
// If an error is encountered, use NCUpdateResultFailed
// If there's no update required, use NCUpdateResultNoData
// If there's an update, use NCUpdateResultNewData
completionHandler(NCUpdateResultNewData);
}
事件監(jiān)聽:
因為Widget是一個獨立的小應(yīng)用
所以需要添加:
主項目里面的AppDelegate:
//在widget進(jìn)入
- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.description hasPrefix:@"widgetMain://"]) {
NSLog(@"%@", url.description);
//一些操作
}
return YES;
}
證書:
首先因為Widget是一個獨立的小應(yīng)用
因此證書也需要另外的一套
Bundle ID:widget的Bundle Id是在主項目的Bundle ID的基礎(chǔ)上加的,例
主項目:
com.dx.widgetTestMain
widget:
com.dx.widgetTestMain.widgetTest
widget的App ID創(chuàng)建的時候要配置 App Groups項,例:
在創(chuàng)建APP ID的時候
勾選App Groups即可
創(chuàng)建APP ID之后,需要去創(chuàng)建一個App Groups
在項目中還需要配置之前給Widget添加的App Groups
如果widget里面要使用主項目里面的類,需要做下面操作:
感謝閱讀
你的支持是我寫作的唯一動力