您的位置:首页 > 产品设计 > UI/UE

玩转iOS开发:iOS 11 新特性《UIKit新特性的基本认识》

2017-12-25 14:49 591 查看
文章分享至我的个人技术博客: https://cainluo.github.io/15099354591154.html 前两篇, 我们讲了
Xcode 9
的一些新特性, 可以更加方便我们去写"
bug
".
如果没有看的朋友可以去看看:
玩转iOS开发:iOS 11 新特性《Xcode 9》 (一)
玩转iOS开发:iOS 11 新特性《Xcode 9》 (二)
那么这一次呢, 我们来简单的了解一下, 在
iOS 11
里,
UIKit
更新了一些什么东西, 可以让我们更加快捷的开发.
转载声明:如需要转载该文章, 请联系作者, 并且注明出处, 以及不能擅自修改本文.

Paste configuration

我们都知道, 在
iOS
有一个东西叫做
UIMenuController
, 它是一个单例, 可以方便我们简单的去做一些复制, 粘贴等等的操作, 但在
iOS 11
这个粘贴功能进化了, 让我们一起来看看吧, 首先我们要有一个工程项目:



简单显示的东西就好.
然后呢, 我们需要有一个用手势操作
UIMenuController
的管理者
MenuManager
, 详细的代码都在工程里, 大家可以去看看.
iOS 11
的时候, 苹果推出了一个东西叫做
UIPasteConfiguration
, 它是直接继承
NSObject
官方解释:
The interface that an object implements to declare its ability to accept specific data types for pasting and for drag and drop activities.
这个东西能用来干嘛呢?

配置粘贴功能

在项目里, 我们默认给
TableView
加了长按手势和点击手势, 便于用来控制
UIMenuController
.
为了方便演示这个配置粘贴的功能, 另外多开了一个控制器, 这里我们需要声明一个全局字符串, 为的就是用来给这个粘贴功能加个唯一的标识:
@property (nonatomic, copy) NSArray<NSString *> *acceptableTypeIdentifiers;
添加了这个唯一标识, 我们就需要在
Cell
里给
copy:
的方法加点修改:
- (BOOL)canBecomeFirstResponder {

return YES;
}

- (BOOL)canPerformAction:(SEL)action
withSender:(id)sender {

return action == @selector(copy:);
}

- (void)copy:(id)sender {

if (self.model == nil) {
return;
}

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.model];

[[UIPasteboard generalPasteboard] setData:data
forPasteboardType:CELL_TYPE];
}
这里面的
CELL_TYPE
就是全局的唯一标识.
还有就是要在需要粘贴功能的控制器
PasteViewController
里也配置一下:
UIPasteConfiguration *pasteConfiguration = [[UIPasteConfiguration alloc] initWithAcceptableTypeIdentifiers:@[CELL_TYPE]];

self.pasteConfiguration = pasteConfiguration;
并且这里我们还要重写一个方法:
- (void)pasteItemProviders:(NSArray<NSItemProvider *> *)itemProviders {

for (NSItemProvider *item in itemProviders) {

[item loadObjectOfClass:TableViewCellModel.class
completionHandler:^(id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {

if (object) {

TableViewCellModel *model = (TableViewCellModel *)object;

dispatch_async(dispatch_get_main_queue(), ^{

self.targetTextField.text = [NSString stringWithFormat:@"复制的内容: %@", model.titleString];
});
}
}];
}
}
用来处理粘贴后的数据.
PS: 这里的
TableViewCellModel
是需要遵守一个
NSItemProviderReading
协议, 并且在内部实现它的协议方法, 详情可以去代码里看看.

拖放的基本认识

iOS 11
, 苹果爸爸终于把拖放的功能添加进来了, 但这个功能真正受益的是
iPad
, 它可以在分屏
App
里实现数据复制和移动, 甚至还可以共享.
我们在拖动的过程中, 数据会被序列化, 然后呈现在用户拖动的系统控制预览中, 在拖动完成后, 序列化的数据会被复制到目的地, 然后反序列化, 最终将这些信息呈献给用户.
而最先获得支持的两个控件就是
UITableView
UICollectionView
. 现在让我们来新建个工程看看是如何操作.
这里我们还是一个简单的
TableView
:



这里我们要介绍两个新的代理
UITableViewDragDelegate
, 和
UITableViewDropDelegate
, 一个分别拖动, 一个分别是放下的代理.
这里我们要声明一个遵守了
NSItemProviderReading
,
NSItemProviderWriting
Model
, 内部实现在工程里查看:
最终我们去实现拖放功能的就是要去实现那两个代理的方法:
#pragma mark - Table View Drag Delegate
- (NSArray<UIDragItem *> *)tableView:(UITableView *)tableView
itemsForBeginningDragSession:(id<UIDragSession>)session
atIndexPath:(NSIndexPath *)indexPath {

ListModel *model = self.dataSource[indexPath.row];

NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithObject:model];

UIDragItem *dragItem = [[UIDragItem alloc] initWithItemProvider:itemProvider];

return @[dragItem];
}

#pragma mark - Table View Drop Delegate
- (void)tableView:(UITableView *)tableView
performDropWithCoordinator:(id<UITableViewDropCoordinator>)coordinator {

if (!coordinator) {
return;
}

NSIndexPath *destinationIndexPath = coordinator.destinationIndexPath;

dispatch_async(dispatch_get_main_queue(), ^{

[tableView performBatchUpdates:^{

[coordinator.items enumerateObjectsUsingBlock:^(id<UITableViewDropItem>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

if (!obj) {
return;
}

NSIndexPath *indexPath = obj.sourceIndexPath;

ListModel *model = self.dataSource[indexPath.row];

[self.dataSource removeObject:model];
[self.dataSource insertObject:model
atIndex:destinationIndexPath.row];

[tableView moveRowAtIndexPath:indexPath
toIndexPath:destinationIndexPath];
}];

} completion:nil];
});
}

- (BOOL)tableView:(UITableView *)tableView
canHandleDropSession:(id<UIDropSession>)session {
return [session canLoadObjectsOfClass:ListModel.class];
}

- (UITableViewDropProposal *)tableView:(UITableView *)tableView
dropSessionDidUpdate:(id<UIDropSession>)session
withDestinationIndexPath:(nullable NSIndexPath *)destinationIndexPath {

return [[UITableViewDropProposal alloc] initWithDropOperation:UIDropOperationMove
intent:UITableViewDropIntentInsertAtDestinationIndexPath];
}
代码写完了之后, 别忘了把
TableView
的拖放功能给打开:
_tableView.dragInteractionEnabled = YES;
效果图这里就不放了, 自己去跑跑
Demo
就好了, 个人认为自己写的代码还是挺规整的~~哈哈
更详细的内容会在后续的文章慢慢讲解.

TableView侧边栏的改进

iOS 8
的时候, 苹果爸爸就为
TableView
引进了侧边栏的功能, 叫做
UITableViewRowAction
, 不过在
iOS 11
的时候, 苹果爸爸又增加了一个更加灵活的东西, 叫做
UISwipeActionsConfiguration
:
我们另外建一个工程来看看, 然后实现我们的配置:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {

UIContextualAction *contextualAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"Add"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {

NSLog(@"Add");
}];

contextualAction.backgroundColor = [UIColor brownColor];

UISwipeActionsConfiguration *swipeActionsCOnfiguration = [UISwipeActionsConfiguration configurationWithActions:@[contextualAction]];

return swipeActionsCOnfiguration;
}

- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView
leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {

UIContextualAction *contextualAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"Copy"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {

NSLog(@"Copy");
}];

contextualAction.backgroundColor = [UIColor blackColor];

UISwipeActionsConfiguration *swipeActionsCOnfiguration = [UISwipeActionsConfiguration configurationWithActions:@[contextualAction]];

return swipeActionsCOnfiguration;
}






关于
TableView
刷新的时候, 我们还有一个专门的
API
:
- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion API_AVAILABLE(ios(11.0), tvos(11.0));
刚刚的拖放功能也是在这里面完成刷新数据源的, 这么做的话, 可以让我们的逻辑结构更加的清晰, 这样子我们也需要在使用
dispatch_async(dispatch_get_main_queue(), ^{});
去更新了, 爽爽滴~~

Asset UIColor的集成

Xcode 9
里,
Asset
里可以集成
UIColor
的目录, 这样子我们就可以省略声明一大堆的颜色, 详细怎么做呢? 我们一起来看看, 这里随便弄一个项目就好了.
然后我们在
Assets.xcassets
里添加
Color Set
:



然后添加自己喜欢的颜色值:





这里我们要看看两个
API
, 都是在
iOS 11
之后才出来的
+ (nullable UIColor *)colorNamed:(NSString *)name

+ (nullable UIColor *)colorNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection
最终效果:



新添加的辅助功能

在讲这个得时候, 这里是需要装有
iOS 11
的真机设备.
但由于我现在手上没有
iOS 11
的设备, 所以这里暂时不说, 有兴趣的话, 可以到百度去搜搜, 或者等我
iOS 11
设备的时候再更新吧.

总结

iOS 11
更多的东西都是在优化和改进开发的流程, 这篇张文章只是简单的介绍一下而已, 还有更多更深层次的可以自行去查阅苹果的官方文档, 或者是去看看
WWDC
的视频演示:
Cococa Touch中的新功能:apple.co/2vy2mOo
更新iOS 11的应用程序:apple.co/2syu3Tt
无障碍新功能:apple.co/2r9EASD

工程地址

项目地址: https://github.com/CainRun/iOS-11-Characteristic/tree/master/2.UIKit
作者:CainLuo
链接:https://juejin.im/post/5a017dd7518825297a0e29ca
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


















 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: