代码之家  ›  专栏  ›  技术社区  ›  KLD

从子VC设置父VC对象的动画

  •  0
  • KLD  · 技术社区  · 6 年前

    是否可以在Swift中设置父VC视图的动画?

    我有一个带UIView的根/主VC,我用它作为一种UIAbbarController,因此我的4个主要VC中的其余部分都是根的子级。

    在一些子VC上,我的子视图应该占据整个屏幕,而没有从根VC看到自定义选项卡栏(UIView),但它仍然浮在上面。

    每当我打开全屏子视图时,我想让它通过Y轴从屏幕上滑下,但是 我似乎无法访问或操作根VCs属性,因为它在运行时返回nil。

    下面是自定义选项卡栏根VC,您可以了解代码的结构:

    class RootVC: UIViewController {
    
        //This is where we pull all of our content from other VCs
        //when a tab bar button is selected
        @IBOutlet weak var contentView: UIView!
    
        //The custom tab bar itself with an array of button outlets
        @IBOutlet public weak var customTabBarContainer: UIView!
        @IBOutlet var tabBarButtons: [UIButton]!
    
        //4 main view VCs that are reflected in the tab bar
        public var mapVC: UIViewController!
        public var favoritesVC: UIViewController!
        public var chatVC: UIViewController!
        public var profileVC: UIViewController!
    
        //Array for the VCs above
        public var viewControllers: [UIViewController]!
    
        //Index of the selected button determend by their tags
        public var selectedIndex: Int = 0
    
        @IBOutlet weak var loadingLogo: UIImageView!
    
        override public func viewDidLoad() {
            //Populating viewControllers array with
            //initiated VCs in Main storyboard
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            mapVC = storyboard.instantiateViewController(withIdentifier: "MapVC")
            favoritesVC = storyboard.instantiateViewController(withIdentifier: "FavoritesVC")
            chatVC = storyboard.instantiateViewController(withIdentifier: "ChatVC")
            profileVC = storyboard.instantiateViewController(withIdentifier: "ProfileVC")
            viewControllers = [mapVC, favoritesVC, chatVC, profileVC]
    
            //Custom tab bar + buttons visual properties
                customTabBarContainer.layer.cornerRadius = customTabBarContainer.frame.height / 2
                customTabBarContainer.layer.shadowColor = UIColor.darkGray.cgColor
                customTabBarContainer.layer.shadowOffset = CGSize.zero
                customTabBarContainer.layer.shadowRadius = 10
                customTabBarContainer.layer.shadowOpacity = 0.9
                tabBarButtons[0].imageView?.contentMode = .scaleAspectFit
                tabBarButtons[1].imageView?.contentMode = .scaleAspectFit
                tabBarButtons[2].imageView?.contentMode = .scaleAspectFit
                tabBarButtons[3].imageView?.contentMode = .scaleAspectFit
    
        }
    
    
        override public func viewDidAppear(_ animated: Bool) {
            loadingLogo.popOut()
            //Loads the initial VC
            contentView.addSubview(mapVC.view)
            mapVC.view.frame = self.view.frame
            mapVC.didMove(toParentViewController: self)
            customTabBarContainer.isHidden = false
            //Selects the inital home button
            tabBarButtons[0].isSelected = true
        }
    
    
        @IBAction func didTabButton(_ sender: UIButton) {
    
            //Keeps a track of which bar button is selected
            let previousIndex = selectedIndex
            selectedIndex = sender.tag
    
            //Deselects the previous bar button
            tabBarButtons[previousIndex].isSelected = false
    
            //Removes the previous VC
            let previousVC = viewControllers[previousIndex]
            previousVC.view.removeFromSuperview()
            previousVC.removeFromParentViewController()
    
            print("switced to \(viewControllers[selectedIndex])")
    
            //Selects the tapped bar button
            tabBarButtons[selectedIndex].isSelected = true
            tabBarButtons[selectedIndex].popIn()
    
            //Brings up the selected VC
            let nextVC = viewControllers[selectedIndex]
            contentView.addSubview(nextVC.view)
            nextVC.view.frame = self.view.frame
            nextVC.didMove(toParentViewController: self)
    
        }
    }
    

    下面是我试图从MapVC的子级操作customTabBarContainer的代码:

        UIView.animate(withDuration: 0.4, animations: {
    
            let root = self.parent?.parent as! RootVC
            root.customTabBarContainer.frame.origin.y -= root.customTabBarContainer.frame.height
    
        }, completion: nil)
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   shayegh    6 年前

    那你为什么要访问父对象的父对象呢?

    self.parent?.parent as RootVC
    

    假设您使用这样的扩展来查找您的父项VC:

    extension UIView {
        var parentViewController: UIViewController? {
            var parentResponder: UIResponder? = self
            while parentResponder != nil {
                parentResponder = parentResponder!.next
                if parentResponder is UIViewController {
                    return parentResponder as! UIViewController!
                }
            }
            return nil
        }
    } 
    

    您应该能够通过

    let root = self.parentViewController as! RootVC
    
        2
  •  0
  •   KLD    6 年前

    我已经想出了一个答案,以防其他人遇到类似的问题。它不会把你带到VCs的直系父母那里,而是带到它最遥远的祖先那里,这就解决了我在这种情况下的特殊问题。

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let rootVC = appDelegate.window?.rootViewController as! RootVC
        rootVC.customTabBarContainer.isHidden = true