【问题标题】:How to removeFromSuperview() with a transition如何使用过渡删除FromSuperview()
【发布时间】:2017-08-28 09:56:43
【问题描述】:

我使用以下代码添加了一个视图作为子视图

    let controller = SideMenuViewController.instantiateViewControllerFromStoryboard(storyBoardName: "Module1") as! SideMenuViewController

    UIView.animate(withDuration:0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
    }, completion: {
        (finished: Bool) -> Void in


        controller.view.tag = 100

        let transition = CATransition()
        transition.type = kCATransitionPush
        transition.subtype = kCATransitionFromLeft
        controller.view.layer.add(transition, forKey: nil)
        self.view.addSubview(controller.view)
        self.addChildViewController(controller)
        controller.didMove(toParentViewController: self)



    })

结果是视图控制器(sidemenu)从左侧滑动并显示。 我想通过从右到左的过渡来删除添加的子视图 我尝试使用以下代码从带有动画的超级视图中删除

UIView.animate(withDuration:0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {}, completion: {


self.view.viewWithTag(100)?.removeFromSuperview()


})

但这不会导致平滑过渡。如何以平滑过渡的方式移除添加的子视图,类似于它的显示方式???

【问题讨论】:

  • 要做到这一点,您只需要在动画方法中更改帧,以便您的视图离开屏幕到最右边,然后在完成处理程序中,一旦动画完成,您调用 removeFromSuperview() 方法跨度>

标签: ios swift addsubview catransition


【解决方案1】:

removeFromSuperview() 方法不可动画化,您可以做的是让 alpha 变为 0,完成后您可以安全地从超级视图中移除。
如果您想获得与推送相同的效果,您只需要获取您的代码并创建相反的转换即可。由于您似乎正在使用视图控制器,因此您可以利用转换 API。

func push(_ viewController: UIViewController, animated: Bool, completion: (()->())?) {
        let oldVC = viewControllersStack.topItem()!
        viewController.view.frame = oldVC.view.frame
        self.addChildViewController(viewController)
        oldVC.willMove(toParentViewController: nil)
        let duration = animated ? Constants.GeneralValues.PopPushAnimationDuration : 0.0
        transition(from: oldVC, to: viewController, duration: duration, options: [], animations: { () -> Void in
            let animation = CATransition()
            animation.duration = CFTimeInterval(duration)
            animation.type = kCATransitionMoveIn
            animation.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")
            animation.subtype = "fromRight"
            animation.fillMode = "forwards"
            self.mainContainerView.layer.add(animation, forKey: "animoteKey")

            // Constraint
            guard let v = viewController.view else {
                return
            }
            v.translatesAutoresizingMaskIntoConstraints = false
            let hConstr = NSLayoutConstraint.constraints(withVisualFormat: "H:|[v]|", options:[], metrics:nil, views:["v":v])
            let vConstr = NSLayoutConstraint.constraints(withVisualFormat: "V:|[v]|", options:[], metrics:nil, views:["v":v])
            let constrs: [NSLayoutConstraint] = [hConstr, vConstr].flatMap {$0}
            NSLayoutConstraint.activate(constrs)
            }) { (finished) -> Void in
            oldVC.removeFromParentViewController()
            self.viewControllersStack.push(viewController)
            viewController.didMove(toParentViewController: self)
            if let completion = completion {
                completion()
            }
        }
    }

    func popViewController(_ animated: Bool, completion: (()->())?) {
        let oldVC = viewControllersStack.topItem()!
        let viewController = viewControllersStack.penultimate!
        viewController.view.frame = oldVC.view.frame
        self.addChildViewController(viewController)
        oldVC.willMove(toParentViewController: nil)
        let duration = animated ? Constants.GeneralValues.PopPushAnimationDuration : 0.0
        transition(from: oldVC, to: viewController, duration: duration, options: [], animations: { () -> Void in
            let animation = CATransition()
            animation.duration = CFTimeInterval(duration)
            animation.type = kCATransitionReveal
            animation.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")
            animation.subtype = "fromLeft"
            animation.fillMode = "forwards"
            self.mainContainerView.layer.add(animation, forKey: "animoteKey")
            // Constraint
            guard let v = viewController.view else {
                return
            }
            v.translatesAutoresizingMaskIntoConstraints = false
            let hConstr = NSLayoutConstraint.constraints(withVisualFormat: "H:|[v]|", options:[], metrics:nil, views:["v":v])
            let vConstr = NSLayoutConstraint.constraints(withVisualFormat: "V:|[v]|", options:[], metrics:nil, views:["v":v])
            let constrs: [NSLayoutConstraint] = [hConstr, vConstr].flatMap {$0}
            NSLayoutConstraint.activate(constrs)

            }) { (finished) -> Void in
            print("Fine")
            oldVC.removeFromParentViewController()
            _ = self.viewControllersStack.pop()
            viewController.didMove(toParentViewController: self)
            if let completion = completion {
                completion()
            }
        }
    }

这是我用来实现您想要的相同的一种实现,但用于在容器中推送和弹出视图控制器,但动画是相同的,只是更改约束,以保持侧视图控制器薄。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    • 2017-11-16
    • 2016-01-16
    • 2015-10-21
    • 1970-01-01
    相关资源
    最近更新 更多