You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xcode 9、Swift 4中创建同时滑入淡入的自定义Segue

嘿,我来帮你搞定这个自定义Segue的问题!其实你不用纠结直接引用leading/trailing约束,自定义转场动画更常用的方式是直接修改视图的位置和透明度,就能实现你要的“右侧滑入+淡入”、“右侧滑出+淡出”效果。下面是具体的实现步骤:

实现带淡入淡出的左右滑动自定义Segue

1. 先写自定义Segue的核心代码

新建一个继承自UIStoryboardSegue的类,比如叫SlideFadePushSegue,代码如下:

import UIKit

class SlideFadePushSegue: UIStoryboardSegue {
    override func perform() {
        // 拿到源控制器和目标控制器的视图
        guard let sourceView = source.view,
              let destView = destination.view else {
            super.perform()
            return
        }
        
        // 设置目标视图的初始状态:在屏幕右侧外,完全透明
        destView.frame = CGRect(x: sourceView.bounds.width, y: 0, width: sourceView.bounds.width, height: sourceView.bounds.height)
        destView.alpha = 0.0
        
        // 把目标视图加到窗口层级里,放在源视图上面
        sourceView.window?.insertSubview(destView, aboveSubview: sourceView)
        
        // 执行动画
        UIView.animate(withDuration: 0.3, animations: {
            // 目标视图滑入屏幕,同时淡入
            destView.frame = sourceView.bounds
            destView.alpha = 1.0
            
            // 可选:让源视图稍微左移一点,更贴近系统Push的视觉感
            sourceView.frame = CGRect(x: -sourceView.bounds.width * 0.1, y: 0, width: sourceView.bounds.width, height: sourceView.bounds.height)
        }) { _ in
            // 动画结束后,完成导航跳转(如果是模态跳转就用present)
            self.source.navigationController?.pushViewController(self.destination, animated: false)
        }
    }
}

2. 处理返回(Pop)的动画效果

如果要在返回时也有对应的滑出+淡出,你可以在目标控制器里自定义返回动作,比如给返回按钮加个点击事件:

@IBAction func backButtonTapped(_ sender: UIButton) {
    guard let nav = navigationController,
          let sourceView = nav.viewControllers[nav.viewControllers.count - 2].view else {
        navigationController?.popViewController(animated: false)
        return
    }
    
    UIView.animate(withDuration: 0.3, animations: {
        // 当前视图滑出屏幕右侧,同时淡出
        self.view.frame = CGRect(x: sourceView.bounds.width, y: 0, width: sourceView.bounds.width, height: sourceView.bounds.height)
        self.view.alpha = 0.0
        
        // 源视图回到原始位置
        sourceView.frame = sourceView.bounds
    }) { _ in
        self.navigationController?.popViewController(animated: false)
    }
}

3. 额外提示

  • 如果是模态跳转(不是导航栏Push),把代码里的pushViewController换成present,返回时用dismiss就行。
  • 动画时长可以自己调,系统默认的Push动画大概是0.3秒,这个数值比较自然。
  • 如果你想做更复杂的转场(比如支持侧滑返回),可以用UINavigationControllerDelegate结合UIViewControllerAnimatedTransitioning来实现,这种方式比单纯的自定义Segue更灵活。

至于你之前想的leading/trailing约束,其实在这种全屏转场场景下没必要用——当然也可以通过修改约束来实现,比如给目标视图加leading约束到父视图的trailing,动画时把约束constant改成0再调用layoutIfNeeded(),但直接改frame会更简单直接~

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:36:49