1.簡單的介紹一下3D Touch
3D Touch的觸控技術(shù),被蘋果稱為新一代多點(diǎn)觸控技術(shù)彪笼。其實(shí),就是此前在Apple Watch上采用的Force Touch,屏幕可感應(yīng)不同的感壓力度觸控律想。
2.在模擬器上如何進(jìn)行3D Touch測試
聲明:可能由于本人技術(shù)水平有限,按照此方法未能在模擬器上實(shí)現(xiàn)3D Touch功能绍弟,所以僅供參考技即!若有能實(shí)現(xiàn)者,請快告訴我喲U燎病6稹!????
3D Touch 是一個很新穎的設(shè)計豹悬,可是蘋果文檔有言:
With Xcode 7.0 you must develop on a device that supports 3D Touch. Simulator in Xcode 7.0 does not support 3D Touch.
看到這句話心是不是涼了一半澈歉,是的,xcode7是支持3D Touch開發(fā)的屿衅,可是模擬器并不支持這個手勢埃难,我們只能在真機(jī)上進(jìn)行學(xué)習(xí)與測試,但是在IT的世界涤久,從來都不缺拯救世界的人物涡尘,github上有人為我們提供了這樣的一個插件,可以讓我們在模擬器上進(jìn)行3D Touch的效果測試:
git地址:https://github.com/DeskConnect/SBShortcutMenuSimulator
附.SBShortcutMenuSimulator的安裝和使用
其實(shí)安裝和使用并不需要怎么介紹响迂,git主頁里介紹的很清楚考抄,這里在記錄一遍,其中只有一點(diǎn)需要注意蔗彤,如果你像我一樣川梅,電腦中裝有Xcode6和Xcode7兩個版本,那個Xcode的編譯路徑然遏,需要做一下修改贫途。
安裝:
在終端中一次運(yùn)行如下指令:
git clone https://github.com/DeskConnect/SBShortcutMenuSimulator.gitcd SBShortcutMenuSimulator
make
如果電腦中有多個Xcode版本,先做如下操作待侵,如果只有Xcode7丢早,則可以跳過
sudo xcode-select -switch /Applications/Xcode2.app/Contents/Developer/
注意:上面命令中,Xcode2.app是你電腦中Xcode的名字,這里如要特別注意怨酝,如果名字中有空格傀缩,需要修改一下,把空格去掉农猬,否則會影響命令的執(zhí)行赡艰。
之后在SBShortcutMenuSimulator的目錄中執(zhí)行如下操作:
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
如果沒有報錯,我們可以通過向指定端口發(fā)送消息的方法來在模擬器上模擬3D Touch的效果:
echo 'com.apple.mobilecal' | nc 127.0.0.1 8000
其中斤葱,com.apple.mobilecal是應(yīng)用的Bundle ID 瞄摊,如果要測試我們的應(yīng)用,將其改為我們應(yīng)用的BundleID即可苦掘,上面的示例應(yīng)用是系統(tǒng)日歷换帜,可以看到模擬器的效果如下:
3.如何實(shí)現(xiàn)3D Touch功能
3D Touch的三大模塊
3D Touch功能主要分為以下三個模塊:
1、Home Screen Quick Actions
通過主屏幕的應(yīng)用Icon鹤啡,我們可以用3D Touch呼出一個菜單惯驼,進(jìn)行快速定位應(yīng)用功能模塊相關(guān)功能的開發(fā)。如上面的日歷递瑰。
2祟牲、peek and pop
這個功能是一套全新的用戶交互機(jī)制,在使用3D Touch時抖部,ViewController中會有如下三個交互階段:
(1)提示用戶這里有3D Touch的交互说贝,會使交互控件周圍模糊
(2)繼續(xù)深按,會出現(xiàn)預(yù)覽視圖
(3)通過視圖上的交互控件進(jìn)行進(jìn)一步交互
? ? ? ? 這個模塊的設(shè)計可以在網(wǎng)址連接上進(jìn)行網(wǎng)頁的預(yù)覽交互慎颗。
3乡恕、Force Properties
iOS9為我們提供了一個新的交互參數(shù):力度。我們可以檢測某一交互的力度值俯萎,來做相應(yīng)的交互處理傲宜。例如,我們可以通過力度來控制快進(jìn)的快慢夫啊,音量增加的快慢等函卒。
4.通過實(shí)例來看是如何實(shí)現(xiàn)3D Touch功能的
用一個簡單的相冊來舉例說明:
首先,創(chuàng)建Quick Action(用力按壓圖標(biāo)出現(xiàn)的標(biāo)簽)有兩種方式:靜態(tài)和動態(tài)
①靜態(tài)創(chuàng)建的方式是在Info.plist文件中進(jìn)行聲明的
有兩種方式進(jìn)行編輯:
(1)第一種方法——如圖所示:
選擇紅色框中的選項(xiàng)
將上面的代碼填入Info.plist文件中
必填項(xiàng)(下面兩個鍵值是必須設(shè)置的):
UIApplicationShortcutItemType 這個鍵值設(shè)置一個快捷通道類型的字符串
UIApplicationShortcutItemTitle 這個鍵值設(shè)置標(biāo)簽的標(biāo)題
選填項(xiàng)(下面這些鍵值不是必須設(shè)置的):
UIApplicationShortcutItemSubtitle 設(shè)置標(biāo)簽的副標(biāo)題
UIApplicationShortcutItemIconType 設(shè)置標(biāo)簽Icon類型
UIApplicationShortcutItemIconFile? 設(shè)置標(biāo)簽的Icon文件
(2)第二種方法
直接在Info.plist文件中添加如下代碼(紅色方框中的代碼):
其實(shí)靜態(tài)添加的兩種方法都是在Info.plist文件中添加的撇眯,只是通過的方式不同报嵌。
②以動態(tài)方式創(chuàng)建
動態(tài)創(chuàng)建是在程序初始化的時候用代碼動態(tài)添加。UIApplication對象多了一個支持快捷方式的數(shù)組(shortcutItems)熊榛,如果需要增加快捷方式锚国,可以賦值給shortcutItems屬性。
可在rootViewController的viewDidLoad中添加(具體寫哪来候,可根據(jù)自己情況而定)跷叉,代碼如下:
UIApplicationShortcutItem * item = [[UIApplicationShortcutItem alloc]initWithType:@"two" localizedTitle:@"標(biāo)簽2" localizedSubtitle:@"222" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLove] userInfo:nil];
// 設(shè)置自定義標(biāo)簽圖片
UIApplicationShortcutItem * itemTwo = [[UIApplicationShortcutItem alloc]initWithType:@"two" localizedTitle:@"標(biāo)簽3" localizedSubtitle:@"333" icon:[UIApplicationShortcutIcon iconWithTemplateImageName:@"jieri"] userInfo:nil];
UIApplicationShortcutItem * itemThird = [[UIApplicationShortcutItem alloc]initWithType:@"two" localizedTitle:@"標(biāo)簽4" localizedSubtitle:@"444" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeSearch] userInfo:nil];
[UIApplication sharedApplication].shortcutItems = @[item, itemTwo, itemThird];
說明:
1)系統(tǒng)限制每個App最多能夠顯示4個Action Item逸雹,其中包括靜態(tài)方式和動態(tài)方式進(jìn)行創(chuàng)建的营搅;
2)如果靜態(tài)和動態(tài)方式同時使用的時候云挟,給UIApplication的shortcutItems賦值的時候不會覆蓋
響應(yīng)回調(diào)
當(dāng)App在后臺的時候UIApplication提供了一個回調(diào)方法
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0);
我們依據(jù)這個回調(diào)中的shortcutItem的type和userinfo來做出不同的事件處理,代碼如下:
// 用來處理3D Touch觸發(fā)事件
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler{
//判斷先前我們設(shè)置的唯一標(biāo)識
if([shortcutItem.localizedTitle isEqualToString:@"標(biāo)簽1"]){
NSArray *arr = @[@"hello 3D Touch"];
UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:arr applicationActivities:nil];
//設(shè)置當(dāng)前的VC 為rootVC
[self.window.rootViewController presentViewController:vc animated:YES completion:^{
}];
}
if ([shortcutItem.localizedTitle isEqual: @"標(biāo)簽2"]) {
// 點(diǎn)擊標(biāo)簽2時转质,顯示提示框
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"OPPS!" message:@"啦啦啦" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alert = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[alertC addAction:alert];
[self.window.rootViewController presentViewController:alertC animated:YES completion:^{
}];
return;
}
}
實(shí)際上就是园欣,當(dāng)我們按壓圖標(biāo),出現(xiàn)標(biāo)簽休蟹,點(diǎn)擊某個標(biāo)簽后觸發(fā)的事件
在rootViewController中創(chuàng)建一個UICollectionView沸枯,并實(shí)現(xiàn)其協(xié)議方法,代碼如下:
- (void)createCollectionView {
UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
/* API */
/* item 大小 */
flow.itemSize = CGSizeMake(100, 100);
/* 行間的最小間距 */
flow.minimumLineSpacing = 5.0f;
flow.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
/* 創(chuàng)建collectionView對象 */
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64) collectionViewLayout:flow];
[self.view addSubview:self.collectionView];
self.collectionView.backgroundColor = [UIColor whiteColor];
/* 兩個協(xié)議 */
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView registerClass:[PicCollectionViewCell class] forCellWithReuseIdentifier:@"pic"];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.arrPic.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PicCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"pic" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.name = [self.arrPic objectAtIndex:indexPath.row];
return cell;
}
整理圖片相關(guān)數(shù)據(jù):
- (void)handleData {
self.arrPic = [NSMutableArray array];
self.arrName = [NSMutableArray array];
for (int i = 1; i < 27; i ++) {
[self.arrPic addObject:[NSString stringWithFormat:@"%d", i]];
[self.arrName addObject:[NSString stringWithFormat:@"%c", i + 64]];
}
}
在自定義Cell中給圖片賦值
需要簽UIViewControllerPreviewingDelegate代理方法赂弓,為了實(shí)現(xiàn)peek and pop功能
(1)peek功能的實(shí)現(xiàn)
Peek窗口的內(nèi)容其實(shí)是目標(biāo)VC【ps即將要顯示的ViewController】的一個實(shí)時快照绑榴,但它不可以點(diǎn)擊。Peek觸發(fā)階段有三種:
長按【顯示一個焦點(diǎn)視圖盈魁,觸發(fā)Peek的源視圖高亮翔怎,其它視圖都處于模糊狀態(tài)】
輕壓【顯示Peek窗口,此時如果Peek窗口支持Quick Actions杨耙,往上滑會顯示Quick Actions菜單赤套,此時的Peek窗口是不可以點(diǎn)擊的】
重壓 【進(jìn)入到真正的ViewController】
Peek由一個可響應(yīng)事件的View觸發(fā),默認(rèn)是關(guān)閉的珊膜,我們需要通過控制器的registerForPreviewingWithDelegate: sourceView:方法注冊容握,第一個參數(shù)為UIViewControllerPreviewingDelegate的代理,Peek觸發(fā)輕壓時會調(diào)用其previewingContext:viewControllerForLocation方法车柠,重壓時會調(diào)用previewingContext:commitViewController:方法剔氏。第二個參數(shù)為觸發(fā)Peek事件的源視圖
首先要在viewDidLoad中進(jìn)行注冊:
// 注冊預(yù)覽視圖的代理和來源視圖
[self registerForPreviewingWithDelegate:(id)self sourceView:self.view];
實(shí)現(xiàn)方法:
#pragma mark - 按壓圖片進(jìn)入預(yù)覽模式
- (UIViewController * _Nullable)previewingContext:(id_Nonnull)previewingContext viewControllerForLocation:(CGPoint)location {
ContentViewController *content = [[ContentViewController alloc] init];
NSIndexPath *index = [self.collectionView indexPathForItemAtPoint:CGPointMake(location.x, location.y - 64 + self.collectionView.contentOffset.y)];
if (index == NULL) {
return nil;
} else {
content.name = [self.arrPic objectAtIndex:index.item];
content.picName = [self.arrName objectAtIndex:index.item];
return content;
}
}
#pragma mark - 繼續(xù)按壓進(jìn)入查看圖片
- (void)previewingContext:(id_Nonnull)previewingContext commitViewController:(UIViewController * _Nonnull)viewControllerToCommit
{
viewControllerToCommit.view.backgroundColor = [UIColor whiteColor];
[self showViewController:viewControllerToCommit sender:self];
}
(2)pop功能的實(shí)現(xiàn)
在創(chuàng)建的ContentViewController中實(shí)現(xiàn)如下代碼:
首先在.h文件中聲明兩個屬性
@property (nonatomic, copy) NSString *name; ?// 圖片的文件名(如xxx.png)
@property (nonatomic, copy) NSString *picName; ?// 圖片名(如自己給圖片起的名字)
在.m文件中實(shí)現(xiàn)如下方法:
// 設(shè)置預(yù)覽視圖向上滑動時出現(xiàn)的視圖
- (NSArray> *)previewActionItems {
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Action 1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
// 點(diǎn)擊此選項(xiàng)觸發(fā)
self.alertC = [UIAlertController alertControllerWithTitle:@"你查看的是:" message:[NSString stringWithFormat:@"圖片%@", self.picName] preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *alert = [UIAlertAction actionWithTitle:@"噢噢" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[self.alertC addAction:alert];
// 因?yàn)轭A(yù)覽視圖與根視圖不在一個視圖層級上,所以需要通過根視圖去推出這個
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:self.alertC animated:YES completion:^{
}];
}];
// 可以添加多個選項(xiàng)
NSArray *arr = @[action1];
return arr;
}
在viewDidLoad中添加如下代碼竹祷,將圖片顯示出來:
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.name]];
image.frame = CGRectMake(20, 0, self.view.frame.size.width - 40, self.view.frame.size.width - 40);
image.center = CGPointMake(self.view.frame.size.width / 2, (self.view.frame.size.height - 64) / 2);
[self.view addSubview:image];
大概總結(jié)到這里介蛉,有待完善。溶褪。币旧。