iOS 15 のアップデート
Apple は新しい API であるUISheetPresentationControllerを導入しました.medium()
。よりカスタムなものを求めている場合は、元の答えが必要です。
let vc = UIViewController()
if let sheet = vc.presentationController as? UISheetPresentationController {
sheet.detents = [.medium()]
}
self.present(vc, animated: true, completion: nil)
元の回答
iOS 7 では、View Controller を提示し、元の View Controller をフォームのようにその下に表示することができます。これを行うには、次の 2 つのことを行う必要があります。
モーダル プレゼンテーション スタイルをカスタムに設定します。
viewControllerToPresent.modalPresentationStyle = UIModalPresentationCustom;
移行デリゲートを設定します。
viewControllerToPresent.transitioningDelegate = self;
この場合、デリゲートを自分自身に設定しましたが、別のオブジェクトにすることもできます。デリゲートは、次のように、プロトコルの 2 つの必須メソッドを実装する必要があります。
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
semiModalAnimatedTransition.presenting = YES;
return semiModalAnimatedTransition;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
return semiModalAnimatedTransition;
}
この時点で、そのSemiModalAnimatedTransition
クラスはどこから来たのか考えているかもしれません。まあ、これはteehan+laxのブログから採用されたカスタム実装です。
クラスのヘッダーは次のとおりです。
@interface SemiModalAnimatedTransition : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) BOOL presenting;
@end
そして実装:
#import "SemiModalAnimatedTransition.h"
@implementation SemiModalAnimatedTransition
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return self.presenting ? 0.6 : 0.3;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect endFrame = fromViewController.view.bounds;
if (self.presenting) {
fromViewController.view.userInteractionEnabled = NO;
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
CGRect startFrame = endFrame;
startFrame.origin.y = endFrame.size.height;
toViewController.view.frame = startFrame;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
toViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
else {
toViewController.view.userInteractionEnabled = YES;
[transitionContext.containerView addSubview:toViewController.view];
[transitionContext.containerView addSubview:fromViewController.view];
endFrame.origin.y = endFrame.size.height;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
fromViewController.view.frame = endFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
@end
最も簡単な解決策ではありませんが、ハッキングを回避し、うまく機能します。デフォルトでは、iOS はトランジションの最後に最初のビュー コントローラを削除するため、カスタム トランジションが必要です。
iOS 8 のアップデート
iOS 8 では、再び風景が変わりました。必要なことは、新しいプレゼンテーション スタイルを使用することだけです.OverCurrentContext
。
viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;