ios - 复制 iOS 邮件应用程序的撰写功能的样式

标签 ios objective-c email

我正在 iOS 8 上构建应用程序,并希望在创建新电子邮件/消息时复制 iOS 邮件应用程序的功能。如下所示:compose view controller 显示在 inbox view controller 之上,但是 compose vc 并没有占据整个屏幕。有没有比修改 View Controller 的框架更简单的方法来做到这一点?谢谢!

enter image description here

最佳答案

这种效果可以通过 UIPresentationController 实现,它在 iOS 8 中可用。Apple 有一个关于这个主题的 WWDC '14 视频以及在这篇文章底部找到的一些有用的示例代码(原始我在这里发布的链接不再有效)。

*该演示名为“LookInside:Presentation Controllers Adaptivity and Custom Animator Objects”。 Apple 的代码中有几个错误与过时的 API 使用相对应,可以通过将损坏的方法名称(在多个地方)更改为以下内容来解决:

initWithPresentedViewController:presentingViewController:

以下是您可以在 iOS 8 邮件应用程序上复制动画的方法。为了达到预期的效果,下载我上面提到的项目,然后你所要做的就是改变一些东西。

首先,转到 AAPLOverlayPresentationController.m 并确保您已实现 frameOfPresentedViewInContainerView 方法。我的看起来像这样:

- (CGRect)frameOfPresentedViewInContainerView
{
    CGRect containerBounds = [[self containerView] bounds];
    CGRect presentedViewFrame = CGRectZero;
    presentedViewFrame.size = CGSizeMake(containerBounds.size.width, containerBounds.size.height-40.0f);
    presentedViewFrame.origin = CGPointMake(0.0f, 40.0f);
    return presentedViewFrame;
}

关键是您希望 presentedViewController 的框架从屏幕顶部偏移,这样您就可以获得一个 View Controller 与另一个 View Controller 重叠的外观(无需模态完全覆盖 presentingViewController)。

接下来,找到AAPLOverlayTransitioner.m中的animateTransition:方法,将其替换为下面的代码。您可能想根据自己的代码进行一些调整,但总的来说,这似乎是解决方案:

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *fromView = [fromVC view];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *toView = [toVC view];

    UIView *containerView = [transitionContext containerView];

    BOOL isPresentation = [self isPresentation];

    if(isPresentation)
    {
        [containerView addSubview:toView];
    }

    UIViewController *bottomVC = isPresentation? fromVC : toVC;
    UIView *bottomPresentingView = [bottomVC view];

    UIViewController *topVC = isPresentation? toVC : fromVC;
    UIView *topPresentedView = [topVC view];
    CGRect topPresentedFrame = [transitionContext finalFrameForViewController:topVC];
    CGRect topDismissedFrame = topPresentedFrame;
    topDismissedFrame.origin.y += topDismissedFrame.size.height;
    CGRect topInitialFrame = isPresentation ? topDismissedFrame : topPresentedFrame;
    CGRect topFinalFrame = isPresentation ? topPresentedFrame : topDismissedFrame;
    [topPresentedView setFrame:topInitialFrame];

    [UIView animateWithDuration:[self transitionDuration:transitionContext]
                          delay:0
         usingSpringWithDamping:300.0
          initialSpringVelocity:5.0
                        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         [topPresentedView setFrame:topFinalFrame];
                         CGFloat scalingFactor = [self isPresentation] ? 0.92f : 1.0f;
                         //this is the magic right here
                         bottomPresentingView.transform = CGAffineTransformScale(CGAffineTransformIdentity, scalingFactor, scalingFactor);

                    }
                     completion:^(BOOL finished){
                         if(![self isPresentation])
                         {
                             [fromView removeFromSuperview];
                         }
                        [transitionContext completeTransition:YES];
                    }];
}

目前,我没有适用于 iOS 8 之前的操作系统版本的解决方案,但如果您有解决方案,请随时添加答案。谢谢。

更新(03/2016):

上面的链接似乎不再有效。可以在此处找到相同的项目:https://developer.apple.com/library/ios/samplecode/LookInside/LookInsidePresentationControllersAdaptivityandCustomAnimatorObjects.zip

更新(12/2019):

在 iOS 13 上以模态方式呈现 View Controller 时,似乎这种过渡样式现在是默认行为。我对以前版本的操作系统持否定态度,但如果您想在自己的应用程序中复制此功能/过渡无需编写大量代码,您可以按原样在 iOS 13 上呈现一个 View Controller ,或者您可以将该 View Controller 的 modalPresentationStyle 设置为 .pageSheet 然后呈现它.

关于ios - 复制 iOS 邮件应用程序的撰写功能的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29017403/

相关文章:

ios - 可选和非可选不能从返回可选的函数返回

iOS heightForRowAtIndexPath 正确计算方式

iphone - UIActionSheet,取消按钮运行方法

objective-c - 列名的 NSPredicate 问题

ios - 无法转换类型 'UITabBarController' Swift 的值

ios - 在Celander中选择日期可以使用iOS中的Vurig-Calendar库给我以前的日期

objective-c - 来自 C#/Java 世界的 iOS 设计模式等价物?

c# - 部署到主机后,使用 Gmail 通过 C# 发送邮件不起作用

email - 使用 Gmail API 发送的邮件中缺少附件,但仅适用于收件人

C#.net 将带有附件的电子邮件排队发送的最佳方式