SlackTextViewController 自定义转场动画:消息界面切换效果

SlackTextViewController 自定义转场动画:消息界面切换效果

【免费下载链接】SlackTextViewController ⛔️**DEPRECATED** ⛔️ A drop-in UIViewController subclass with a growing text input view and other useful messaging features 【免费下载链接】SlackTextViewController 项目地址: https://gitcode.com/gh_mirrors/sl/SlackTextViewController

在消息应用开发中,转场动画是提升用户体验的关键元素。本文将详细介绍如何基于 SlackTextViewController 实现消息界面的平滑切换效果,包括模态弹窗、导航控制器切换和自定义手势驱动动画。

基础概念与准备工作

SlackTextViewController 是一个功能丰富的消息界面组件,提供了文本输入、自动扩展、键盘处理等核心功能。其核心类 SLKTextViewController 定义了视图控制器的基础行为,可通过继承和重写方法实现自定义动画逻辑。

关键文件与类结构

  • 核心控制器Source/SLKTextViewController.h 定义了 SLKTextViewController 类,包含视图管理、键盘处理和交互事件等核心方法。
  • 动画相关属性bounces 属性控制动画是否启用弹性效果(默认 YES),可通过设置该属性调整转场动画的物理特性。
  • 生命周期方法viewWillAppear:viewDidAppear: 等方法可用于在视图切换时插入动画逻辑。

项目资源

项目提供了多个示例工程,可参考 Examples/Messenger-Programatic/Examples/Messenger-Storyboard/ 中的实现方式,了解视图控制器的组织和交互逻辑。

实现模态转场动画

模态转场是消息应用中常见的场景(如从会话列表进入聊天界面)。通过重写 SLKTextViewController 的转场相关方法,可实现自定义动画效果。

1. 设置模态转场样式

在调用 presentViewController:animated:completion: 前,需设置目标控制器的 modalPresentationStyletransitioningDelegate

// 在源控制器中设置
MessageViewController *vc = [[MessageViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationCustom;
vc.transitioningDelegate = self;
[self presentViewController:vc animated:YES completion:nil];

2. 实现转场动画协议

自定义转场动画需实现 UIViewControllerTransitioningDelegateUIViewControllerAnimatedTransitioning 协议:

// 转场动画实现类
@interface MessageTransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end

@implementation MessageTransitionAnimator

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.3; // 动画时长
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    
    // 设置初始位置(右侧外部)
    toVC.view.frame = CGRectMake(containerView.bounds.size.width, 0, containerView.bounds.size.width, containerView.bounds.size.height);
    [containerView addSubview:toVC.view];
    
    // 执行平移动画
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toVC.view.frame = containerView.bounds;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}
@end

3. 在 SLKTextViewController 中集成

在自定义的 SLKTextViewController 子类中,重写 viewWillAppear: 方法以应用动画参数:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 禁用默认动画,使用自定义逻辑
    self.transitioningDelegate = self.animator;
}

导航控制器转场动画

当使用 UINavigationController 管理消息界面时,可通过自定义导航转场实现滑动切换效果。

1. 自定义导航转场代理

创建遵循 UINavigationControllerDelegate 的代理类,实现 navigationController:animationControllerForOperation:fromViewController:toViewController: 方法:

@interface MessageNavigationAnimator : NSObject <UINavigationControllerDelegate>
@end

@implementation MessageNavigationAnimator

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController *)fromVC
                                                 toViewController:(UIViewController *)toVC {
    if (operation == UINavigationControllerOperationPush) {
        return [[PushAnimator alloc] init]; // 推入动画
    } else if (operation == UINavigationControllerOperationPop) {
        return [[PopAnimator alloc] init]; // 弹出动画
    }
    return nil;
}
@end

2. 推入动画实现

PushAnimator 类实现从右向左的滑动效果:

@implementation PushAnimator

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.3;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    
    CGRect screenBounds = [UIScreen mainScreen].bounds;
    toVC.view.frame = CGRectOffset(screenBounds, screenBounds.size.width, 0);
    [containerView addSubview:toVC.view];
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromVC.view.frame = CGRectOffset(fromVC.view.frame, -screenBounds.size.width * 0.3, 0);
        toVC.view.frame = screenBounds;
    } completion:^(BOOL finished) {
        fromVC.view.frame = screenBounds;
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}
@end

3. 集成导航控制器

在应用启动时配置导航控制器的代理:

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ConversationListViewController alloc] init]];
nav.delegate = [[MessageNavigationAnimator alloc] init];
self.window.rootViewController = nav;

手势驱动转场动画

结合 UIPanGestureRecognizer 实现手势控制的转场效果,提升交互体验(如右滑返回上一界面)。

1. 添加手势识别器

在 SLKTextViewController 的子类中添加手势:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [self.view addGestureRecognizer:panGesture];
}

2. 实现手势处理逻辑

在手势回调中计算滑动距离,动态更新视图位置:

- (void)handlePan:(UIPanGestureRecognizer *)gesture {
    CGPoint translation = [gesture translationInView:self.view];
    CGFloat progress = translation.x / self.view.bounds.size.width;
    
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
            // 开始转场
            [self.navigationController popViewControllerAnimated:NO];
            break;
        case UIGestureRecognizerStateChanged:
            // 更新转场进度
            [self updateTransitionWithProgress:progress];
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
            // 根据进度决定完成或取消转场
            if (progress > 0.3) {
                [self completeTransition];
            } else {
                [self cancelTransition];
            }
            break;
        default:
            break;
    }
}

3. 结合弹性动画

利用 SLKTextViewController 的 bounces 属性实现弹性效果:

- (void)completeTransition {
    [UIView animateWithDuration:0.2 animations:^{
        self.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    } completion:^(BOOL finished) {
        [self.navigationController popViewControllerAnimated:NO];
    }];
}

高级动画技巧与最佳实践

1. 键盘状态与转场协同

SlackTextViewController 提供了键盘状态通知(如 SLKKeyboardWillShowNotification),可在转场时同步调整键盘状态:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:SLKKeyboardWillShowNotification object:nil];

- (void)keyboardWillShow:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    NSValue *keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
    // 根据键盘位置调整动画参数
}

2. 性能优化

  • 减少视图层级:转场时隐藏不必要的子视图,降低渲染压力。
  • 使用硬件加速:通过设置 layer.shouldRasterize = YES 优化动画性能。
  • 避免阻塞主线程:复杂计算放入后台线程,动画相关操作在主线程执行。

3. 示例效果参考

项目截图展示了不同转场动画的效果:

  • 自动扩展输入框自动扩展效果
  • 编辑模式切换编辑模式

总结

通过重写 SLKTextViewController 的方法、实现转场协议和手势处理,可灵活定制消息界面的切换动画。结合项目提供的示例代码 Examples/ 和核心类 Source/SLKTextViewController.m,开发者可快速集成自定义动画,提升应用的交互体验。

建议优先参考官方文档 README.md 和示例工程,确保自定义逻辑与组件的核心功能兼容。如需进一步扩展,可研究 SLKTextInputbarSLKTextView 等类的实现,深入理解视图层级和布局逻辑。

【免费下载链接】SlackTextViewController ⛔️**DEPRECATED** ⛔️ A drop-in UIViewController subclass with a growing text input view and other useful messaging features 【免费下载链接】SlackTextViewController 项目地址: https://gitcode.com/gh_mirrors/sl/SlackTextViewController

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值