Good articles to my personal technology blog: https://cainluo.github.io/15099354591154.html
In the last two articles, we talked about some new features in Xcode 9 that make it easier to write “bugs “.
If you do not see the friends can go to see:
- Xcode 9 is a new feature in iOS 11.
- Xcode 9 is a new feature in iOS 11.
So this time, let’s take a quick look at what UIKit has updated in iOS 11 to help us develop faster.
Reprint statement: if you need to reprint this article, please contact the author, and indicate the source, and can not modify this article without authorization.
Paste configuration
As we all know, there is a thing called UIMenuController in iOS. It is a singleton, which allows us to do some simple operations like copy and paste, but in iOS 11 the paste function has evolved. Let’s take a look.
Just something simple to display.
Then, we need to have a manager MenuManager that uses gestures to operate UIMenuController, the detailed code is in the project, you can go to see.
In iOS 11, Apple came out with something called UIPasteConfiguration, which is a direct inheritance of NSObject.
The interface that an object implements to declare its ability to accept specific data types for pasting and for drag and drop activities.
What can this be used for?
Configuring the Paste Function
In the project, by default, we added a long press gesture and a click gesture to the TableView to control the UIMenuController.
In order to demonstrate the paste function, we need to declare a global string to give the paste function a unique identifier:
@property (nonatomic.copy) NSArray<NSString *> *acceptableTypeIdentifiers;
Copy the code
With this unique identifier, we need to add a change to the copy: method in the Cell:
- (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];
}
Copy the code
Here, CELL_TYPE is the unique identifier of the global.
Also, configure it in the PasteViewController that requires the paste function:
UIPasteConfiguration *pasteConfiguration = [[UIPasteConfiguration alloc] initWithAcceptableTypeIdentifiers:@[CELL_TYPE]];
self.pasteConfiguration = pasteConfiguration;
Copy the code
And here we have to rewrite a method:
- (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:@" Content copied: %@", model.titleString]; }); }}]; }}Copy the code
Used to process pasted data.
PS: hereTableViewCellModel
There is one that needs to be followedNSItemProviderReading
Protocol, and internal implementation of its protocol method, details can go to the code to see.
Basic understanding of drag and drop
In iOS 11, Apple’s dad finally added drag and drop, but the real benefit of this feature is the iPad, which can copy and move data between split-screen apps and even share them.
As we drag, the data will be serialized, and then displayed in the system control preview that the user drags. After the drag is complete, the serialized data will be copied to the destination, then deserialized, and finally presented to the user.
The first two controls to gain support were UITableView and UICollectionView. Now let’s create a new project to see how it works.
Here we have a simple TableView:
So here we’re going to introduce two new proxies UITableViewDragDelegate and UITableViewDropDelegate, one for dragging, one for dropping.
NSItemProviderReading, NSItemProviderWriting, NSItemProviderWriting
The last thing we need to implement drag and drop is to implement the two proxy methods:
#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];
}
Copy the code
After writing the code, don’t forget to turn on the drag and drop function of the TableView:
_tableView.dragInteractionEnabled = YES;
Copy the code
I will not put the renderings here, I will run the Demo. I think the code I wrote is quite neat ~~ haha
More details will be explained in subsequent articles.
TableView sidebar improvements
In iOS 8, Apple introduced a sidebar feature for TableViews called UITableView Action, but in iOS 11, Apple added a more flexible feature, Called UISwipeActionsConfiguration:
Let’s create another project to look at and implement our configuration:
- (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;
}
Copy the code
We also have a special API for TableView refresh:
- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion API_AVAILABLE(ios(11.0), tvos(11.0));
Copy the code
Dispatch_async (dispatch_get_main_queue(), ^{}); To update, cool drop
Asset UIColor integration
In Xcode 9, Asset can integrate with UIColor’s directory, so we can skip declaring a bunch of colors. How do we do that? Let’s take a look at it. We can just pick a random project here.
Then we add Color Set to assets.xcassets:
Then add your favorite color value:
Here we’re going to look at two apis, both of which came out after iOS 11
+ (nullable UIColor *)colorNamed:(NSString *)name
+ (nullable UIColor *)colorNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection
Copy the code
End result:
Newly added accessibility features
While we’re at it, here’s a real device with iOS 11.
However, since I do not have an iOS 11 device, I will not talk about it here for the time being. If you are interested, you can go to Baidu to search, or update it when I have an iOS 11 device.
conclusion
In iOS 11, there are more things to optimize and improve the development process. This article is just a brief introduction, and you can also check out the official Documentation of Apple, or watch the WWDC video demo:
- New in Cococa Touch: apple.co/2vy2mOo
- Update iOS 11 app: apple.co/2syu3Tt
- New barrier-free feature: apple.co/2r9EASD
The project address
The address of the project: https://github.com/CainRun/iOS-11-Characteristic/tree/master/2.UIKit