ObjecTips

基本Objective-Cで iOS とか OS X とか

iOS 11 UIKit の変更点

UIKit | Apple Developer Documentation

UIKit 周りざっくり、網羅はしていない。

iOS 11 関連記事
iOS 11 Foundation の変更点 - ObjecTips
iOS 11 Messages Framework の変更点 - ObjecTips
iOS 11 PDFKit - ObjecTips
iOS 11 Core Image の変更点 - ObjecTips
Vision framework でテキスト検出 TextDetection - ObjecTips
Vision Framework で水平角検出(傾き) Horizon Detection - ObjecTips

変更点

ContentSizeCategory の比較とアクセシビリティチェックの関数が追加
UIKIT_EXTERN BOOL UIContentSizeCategoryIsAccessibilityCategory(UIContentSizeCategory category) API_AVAILABLE(ios(11.0),tvos(11.0),watchos(4.0)) NS_REFINED_FOR_SWIFT;
UIKIT_EXTERN NSComparisonResult UIContentSizeCategoryCompareToCategory(UIContentSizeCategory lhs, UIContentSizeCategory rhs) API_AVAILABLE(ios(11.0),tvos(11.0),watchos(4.0)) NS_REFINED_FOR_SWIFT;
ドラッグ&ドロップ周りの追加クラスやプロトコル

UIPasteConfiguration
UIPasteConfigurationSupporting
UIInteraction
UICollectionViewDragDelegate UICollectionViewDropDelegate
UICollectionViewReorderingCadence
UITableViewDragDelegate UITableViewDropDelegate

NSFileProviderExtension

NSFileProviderExtension - FileProvider | Apple Developer Documentation

Extension からフォルダを作ったりファイルをリネームしたり tag とか favoriteRank を編集したり出来るようになるらしい。

UITextDocumentProxy
@property (nullable, nonatomic, readonly) NSString *selectedText API_AVAILABLE(ios(11.0));

ユーザが選択中のテキストを取得できるようになった。
キーボードExtensionで入力中のテキストから再変換をかけたり絵文字に変換したりといった機能を実装出来そう。

@property (nonatomic, readonly, copy) NSUUID *documentIdentifier API_AVAILABLE(ios(11.0));

用途が思いつかない。
新しくテキスト入力しているのか、前回中断したテキスト入力作業の続きかを判断するのに使える?

UIInputViewController
@property (nonatomic, readonly) BOOL hasFullAccess API_AVAILABLE(ios(11.0));

キーボードアプリからフルアクセスが許可されているかどうかの状態チェックが可能に。
確か以前はユーザデータにアクセスしてみてアクセス出来なかったらフルアクセスが許可されていない、みたいな方法でチェックする必要があったはず。

@property (nonatomic, readonly) BOOL needsInputModeSwitchKey API_AVAILABLE(ios(11.0));

おそらくiOS 11では地球儀ボタンの表示が必要な時とそうでないケースがあるっぽい。

UIView
@property(nonatomic) BOOL accessibilityIgnoresInvertColors API_AVAILABLE(ios(11_0), tvos(11_0));

これを YES にすると、アクセシビリティの白黒反転をViewとそのSubviewsでは反映しないように出来るらしい。
画像やビデオなど表示される色が変わると困るものに対して使うような用途を想定しているらしい。

UICollectionView
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSpringLoadItemAtIndexPath:(NSIndexPath *)indexPath withContext:(id<UISpringLoadedInteractionContext>)context API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos, watchos);

NO を返すと Spring Loading? のオプトアウトが出来るらしい。

その他 UICollectionViewDragDelegate UICollectionViewDropDelegate
UICollectionViewReorderingCadence
などドラッグ&ドロップ周りのAPIがいくつか追加

UITableView
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);

テーブルセルの横スワイプ時のボタン表示機能を提供する UITableViewRowAction の進化版の UIContextualAction が追加。
これを UISwipeActionsConfiguration と組み合わせて使うらしい。
UITableViewRowAction ではタイトルと背景色しか設定出来なかったのが画像も設定出来るようになっている。
さらに UISwipeActionsConfiguration の設定で、メールアプリで使われているようなフルスワイプした時のアクションの実行を実装出来る。(セルのスワイプで表示されるボタンを押さなくても、スワイプ操作だけでアクションを起こす事が出来るという事)

- (BOOL)tableView:(UITableView *)tableView shouldSpringLoadRowAtIndexPath:(NSIndexPath *)indexPath withContext:(id<UISpringLoadedInteractionContext>)context API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos, watchos);

NO を返すと Spring Loading? のオプトアウトが出来るらしい。

- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion API_AVAILABLE(ios(11.0), tvos(11.0));

UICollectionView で既にあるバッチ更新が追加

その他 UITableViewDragDelegate UITableViewDropDelegate
などドラッグ&ドロップ周りのAPIがいくつか追加

UIScrollView

UIViewControllerautomaticallyAdjustsScrollViewInsets

@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets;

が deprecated になって、代わりに UIScrollView に adjust inset 関連のAPIが色々と追加された。
今後はこっちでうまく制御しろという事か。

@property(nonatomic, readonly) UIGestureRecognizer *directionalPressGestureRecognizer API_DEPRECATED("Configuring the panGestureRecognizer for indirect scrolling automatically supports directional presses now, so this property is no longer useful.", tvos(9.0, 11.0));

ドキュメントでは追加メソッドだけどヘッダを見たら deprecated になっているのでリリースまでに消えて無くなるかも、、

UIImageView
@property (nonatomic, strong, readonly) UIView *overlayContentView UIKIT_AVAILABLE_TVOS_ONLY(11_0);

tvOS 用のメソッド。UIImageView の上に重ねてViewを表示する、、ってのがこれまで tvOS では出来なかったのかな。

UIButton
UIButtonTypePlain

tvOS 用のメソッド 。ブラー背景の無いシステム標準ボタンらしい。

UIBarButtonItem

UIBarButtonSystemItemPageCurl が deprecated

UINavigationBar
@property (nonatomic, readwrite, assign) BOOL prefersLargeTitles UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(11.0)); //API_UNAVAILABLE(tvos)

iOS 11の電話アプリの様にタイトル表示を大きくする設定。

UIViewController
@property(nonatomic,readonly,strong) id<UILayoutSupport> topLayoutGuide API_DEPRECATED_WITH_REPLACEMENT("-[UIView safeAreaLayoutGuide]", ios(7.0,11.0), tvos(7.0,11.0));
@property(nonatomic,readonly,strong) id<UILayoutSupport> bottomLayoutGuide API_DEPRECATED_WITH_REPLACEMENT("-[UIView safeAreaLayoutGuide]", ios(7.0,11.0), tvos(7.0,11.0));

layoutGuide が deprecated、safeAreaLayoutGuide ってのを使うらしい。
layoutGuide は結構使ってるので分岐が面倒そう。

@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0)); // Defaults to YES

deprecated、UIScrollViewcontentInsetAdjustmentBehavior を使えとの事。

UISplitViewController
@property(nonatomic) UISplitViewControllerPrimaryEdge primaryEdge API_AVAILABLE(ios(11.0), tvos(11.0)); // default: UISplitViewControllerPrimaryEdgeLeading

先頭と後ろとどっちが primary かを設定出来るらしい。設定するとどう変わるのかは不明。

UINavigationItem
@property (nonatomic, readwrite, assign) UINavigationItemLargeTitleDisplayMode largeTitleDisplayMode API_AVAILABLE(ios(11.0)); //API_UNAVAILABLE(tvos)

ラージタイトルの表示モード

UINavigationBar
@property (nonatomic, readwrite, assign) BOOL prefersLargeTitles UI_APPEARANCE_SELECTOR API_AVAILABLE(ios(11.0)); //API_UNAVAILABLE(tvos)

ラージタイトルの表示設定

NSLayoutXAxisAnchor, NSLayoutYAxisAnchor
- (NSLayoutConstraint *)constraintEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintGreaterThanOrEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintLessThanOrEqualToSystemSpacingAfterAnchor:(NSLayoutXAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));

- (NSLayoutConstraint *)constraintEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintGreaterThanOrEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));
- (NSLayoutConstraint *)constraintLessThanOrEqualToSystemSpacingBelowAnchor:(NSLayoutYAxisAnchor *)anchor multiplier:(CGFloat)multiplier API_AVAILABLE(ios(11.0),tvos(11.0));

iOS 11では system space っていう概念が追加されるらしい。

UIImagePickerController
@property(nonatomic)           UIImagePickerControllerQualityType    videoQuality NS_DEPRECATED_IOS(3_1, 11_0, "Use videoExportPreset");         // default value is UIImagePickerControllerQualityTypeMedium. If the cameraDevice does not support the videoQuality, it will use the default value.

取得するビデオの画質設定が deprecated、videoExportPreset を使えとの事。

@property(nonatomic, copy)     NSString                              *videoExportPreset NS_AVAILABLE_IOS(11_0);   // default value is AVAssetExportPresetMediumQuality. NSString (of one of the AVAssetExportPreset* constants). // Specifying a value for videoExportPreset will override a value specified for videoQuality

取得するビデオの画質設定方法が AVFoundation ベースに変更。プリセットは豊富なので以前より柔軟になった。

@property(nonatomic) UIImagePickerControllerImageURLExportPreset imageExportPreset NS_AVAILABLE_IOS(11_0);   // default value is UIImagePickerControllerImageExportPresetCompatible.

取得する画像の画質設定っぽいけど、ドキュメントにもヘッダにも詳細の記載が無いので不明

UIKIT_EXTERN NSString *const UIImagePickerControllerReferenceURL        NS_DEPRECATED_IOS(4_1, 11_0, "Replace with public API: UIImagePickerControllerPHAsset") __TVOS_PROHIBITED;  // an NSURL that references an asset in the AssetsLibrary framework
UIKIT_EXTERN NSString *const UIImagePickerControllerPHAsset NS_AVAILABLE_IOS(11_0) __TVOS_PROHIBITED;  // a PHAsset
UIKIT_EXTERN NSString *const UIImagePickerControllerImageURL NS_AVAILABLE_IOS(11_0) __TVOS_PROHIBITED;  // an NSURL

URL取得のキーが deprecated になって、PHAsset と画像のURLを指定して取得出来る様になった。

UIDocumentBrowserViewController

ローカルとiCloudのファイルにアクセス出来るらしい。
表示する contentType の指定やドキュメント作成の可否、複数項目の選択可否など macOS の NSOpenPanel ライクに使えそう。

UIDocumentPickerViewController
@property (nonatomic, assign) BOOL allowsMultipleSelection NS_AVAILABLE_IOS(11_0);
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls NS_AVAILABLE_IOS(11_0);

複数項目の選択取得に対応

UIActivityType
UIActivityTypeMarkupAsPDF

アクティビティタイプの追加

Drag & Drop

追加が多いので以下URLで

Drag and Drop | Apple Developer Documentation

Drag and Drop Customization | Apple Developer Documentation

Accessibility
UIKIT_EXTERN NSString *const UIAccessibilityVoiceOverStatusChanged API_DEPRECATED_WITH_REPLACEMENT("UIAccessibilityVoiceOverStatusDidChangeNotification", ios(4.0, 11.0), tvos(9.0, 11.0));
UIKIT_EXTERN NSNotificationName const UIAccessibilityVoiceOverStatusDidChangeNotification API_AVAILABLE(ios(11.0), tvos(11.0));

ボイスオーバーのオンオフの変更通知の名称が変更。StatusChangedStatusDidChangeNotification のワードに変更しただけ。

UIGestureRecognizer
@property (nullable, nonatomic, copy) NSString *name API_AVAILABLE(ios(11.0), tvos(11.0)); // name for debugging to appear in logging

identifier として name を設定出来る様になった。ただヘッダのコメントではデバッグのためって書いてあるので、name で処理分岐を行ったりするのは適切では無さそう。

UIGraphicsImageRendererFormat
+ (instancetype)formatForTraitCollection:(UITraitCollection *)traitCollection NS_AVAILABLE_IOS(11_0);

UITraitCollection を引数に format を作成してくれるメソッドらしいだけど、scale とか UIGraphicsImageRendererFormat のパラメータを自分で設定するなら使う機会が無いかも。

UIColor
+ (nullable UIColor *)colorNamed:(NSString *)name NS_AVAILABLE_IOS(11_0);      // load from main bundle
+ (nullable UIColor *)colorNamed:(NSString *)name inBundle:(nullable NSBundle *)bundle compatibleWithTraitCollection:(nullable UITraitCollection *)traitCollection NS_AVAILABLE_IOS(11_0);

Named Color Assets 関連のメソッド。
Xcode 9では xcassets で画像と同じ様に色をアセットとして作成する事ができて、これらのメソッドで呼び出して使ったり Storyboard 上からも呼び出す事ができる。
カラーアセットを使えば全ボタンの色を変更したりアプリ全体の色管理が容易になるはず。

UIFontMetrics

ドキュメント無し

UITextInputTraits
UIKIT_EXTERN UITextContentType const UITextContentTypeUsername                  NS_AVAILABLE_IOS(11_0);
UIKIT_EXTERN UITextContentType const UITextContentTypePassword                  NS_AVAILABLE_IOS(11_0);

キーボードの入力タイプにユーザ名とパスワード用の入力タイプが追加

UITextSmartQuotesType
UITextSmartDashesType
UITextSmartInsertDeleteType

macOS のスマート引用符とスマートダッシュに相当する入力テキストの自動置き換え機能だと推測。
最後のは英語キーの時のスペースの自動入力と削除?


以下UIKitじゃ無いけどUI周りなのでまとめて

EventKitUI
EVENTKITUI_EXTERN NSBundle *EventKitUIBundle(void);

これ Private で使ってるAPIじゃないの?開発者には利用のしようが無い気がする。

MessageUI MFMailComposeViewController
- (void)setPreferredSendingEmailAddress:(NSString *)emailAddress API_AVAILABLE(ios(11.0));

メール送信UIで送信元(自分)のアドレスを指定出来る様になったらしい。
アプリの使用者のメールアドレスを把握している必要があるので一般向けではなく社内向け用の業務アプリとかで活用出来そう。


まとめ

Named Color Assets の機能が最高。これは本当に色管理が楽になるはず。
あと UIDocumentBrowserViewController はユーザにとって便利で、これに対応しているどうかでアプリを選ぶ人も出てきそうな気がするので積極的に使っていきたい。
開発的にもこのクラスを使っておけばドキュメントの受け渡しの面倒な処理をしなくて良さそうなのでいい事尽くめだと思う。