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

来源:互联网 发布:the mac is invalid. 编辑:程序博客网 时间:2024/05/22 08:30

文章分享至我的个人技术博客: 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这个粘贴功能进化了, 让我们一起来看看吧, 首先我们要有一个工程项目:

1

简单显示的东西就好.

然后呢, 我们需要有一个用手势操作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里实现数据复制和移动, 甚至还可以共享.

我们在拖动的过程中, 数据会被序列化, 然后呈现在用户拖动的系统控制预览中, 在拖动完成后, 序列化的数据会被复制到目的地, 然后反序列化, 最终将这些信息呈献给用户.

而最先获得支持的两个控件就是UITableViewUICollectionView. 现在让我们来新建个工程看看是如何操作.

这里我们还是一个简单的TableView:

2

这里我们要介绍两个新的代理UITableViewDragDelegate, 和UITableViewDropDelegate, 一个分别拖动, 一个分别是放下的代理.

这里我们要声明一个遵守了NSItemProviderReading, NSItemProviderWritingModel, 内部实现在工程里查看:

最终我们去实现拖放功能的就是要去实现那两个代理的方法:

#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 *)tableViewperformDropWithCoordinator:(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 *)tableViewcanHandleDropSession:(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 *)tableViewleadingSwipeActionsConfigurationForRowAtIndexPath:(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;}

3
4

关于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:

5

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

6

7

这里我们要看看两个API, 都是在iOS 11之后才出来的

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

最终效果:

8


新添加的辅助功能

在讲这个得时候, 这里是需要装有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
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 中国风元素图片 中国风名字 中国风花纹 中国风桌面 中国风街舞 中国风纹身 中国风画册 中国风照片 中国风的舞蹈 中国风手抄报 中国风模板 中国风美甲 中国风妆容 中国风窗户 中国风花边 中国风全家福 中国风油画 中国风信纸 中国风 装修 中国风服装秀 中国风化妆品 中国风蛋糕 中国风素描 中国风书房 中国风钢琴 中国风走秀 中国风包装盒 中国风展板 中国风屏风 风歌 中国科学技术馆 中国科技馆 中国科学馆 中国数字科技馆 中国馆 中国科技馆门票预约 中国海洋馆排名 中国足踩馆 中国科技馆一日游攻略 中国科学技术馆旅游 中国馆图片