在Swift中从另一个视图控制器呈现子类化的视图控制器

3

我在使用Swift中的子类时遇到了一些问题,希望有人能够帮助我。

我的情况

两个视图控制器:

VC1 只有一些UIButtons

EffectVC 根据在VC1上按下的按钮执行一些动画

import UIKit

protocol viewAnimation {
    func initialStateSet()
    func finalStateSet()
}

class EffectVC: UIViewController {

    @IBOutlet weak var mainImage: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.initialStateSet()
    }

    override func viewDidAppear(animated: Bool) {
        self.finalStateSet()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func initialStateSet() {
    }

    func finalStateSet() {
    }
}

class GrowingEffect : EffectVC, viewAnimation {

    override func initialStateSet() {
        // some stuff
    }

    override func finalStateSet() {
        // other stuff
    }
}

问题

也许这是一个简单的问题,但我在Swift中无法做到我想要的:我需要根据按下的按钮设置子类。

换句话说,我需要根据VC1上按下的按钮从我的VC1中呈现子类化视图控制器。

例如,如果我按下第一个按钮,我想使用GrowingEffect类显示VC 2以使用一些自定义内容(此内容必须根据所选按钮更改)。

我尝试过的

  1. 使用IBAction创建我的子类化VC2并显示它

    let storyboard = UIStoryboard(name:“Main”,bundle:nil)

    let destinationViewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier(“EffectVC”) as!GrowingEffect

    self.presentViewController(destinationViewController,animated:true,completion:nil)

但我得到了

无法将类型为“ViewAnimationDemo.EffectVC”(0x109948570)的值转换为“ViewAnimationDemo.GrowingEffect”(0x109948650)。

  1. 使用PrepareForSegue

但我无法设置任何子类

我真正想做的事情

我知道还有其他解决方案,比如不使用storyboard,但现在我描述我想要做的事情,希望这是可能的:

在IB中只有一个视图控制器(EffectVC),与类EffectVC相关联。类EffectVC具有一些子类,如GrowingEffect。

在我的代码中,我想使用我需要的子类实例化视图控制器EffectVC:例如,使用GrowingEffect类在IB中实例化视图控制器EffectVC

我知道如果对于EffectVC的每个子类都有一个视图控制器,我可以做到这一点,但我不希望在IB中有这么多视图控制器,因为它们是相同的,我想要更改的唯一内容是2种方法。

2个回答

2
我认为您的设置有些混乱。您应该有两个视图控制器,每个都在其文件中设置,并且每个都在故事板中使用其标识符呈现。如果 GrowingEffect 继承自 EffectVC,那么也可以。
您当前使用的 as! GrowingEffect 实际上是尝试将从调用 instantiateViewControllerWithIdentifier("EffectVC") 获得的 UIViewController 实例转换为 GrowingEffect。这不起作用,因为它是 EffectVC 类型。
相反,如果按下按钮 X,则需要调用 instantiateViewControllerWithIdentifier("EffectVC"),如果按下按钮 Y,则需要调用 instantiateViewControllerWithIdentifier("GrowingEffect")
编辑
如果您使用故事板,则必须使用 instantiateViewControllerWithIdentifier 实例化视图控制器。但是,只有当 GrowingEffect 存在于故事板上时,您才能获得其实例。
一旦创建了 EffectVC 的实例,就无法将其“转换”为 GrowingEffect
因此,在这里您有两种可能性:
1. 使用故事板并将两个视图控制器放在其中。根据按下的按钮,使用 instantiateViewControllerWithIdentifier 实例化所需的视图控制器。
2. 不使用故事板。然后,您可以手动创建所需的视图控制器,并使用您的 UINavigationControllerpushViewController 方法来呈现它。

好的,我知道这个解决方案,但我需要在Interface Builder 2视图控制器中设置...是否有一种使用一个父类和子类以及一个视图控制器的解决方案? - Massimo Polimeni
您还可以创建子类的实例并手动呈现它。也就是说,如果您愿意,您不需要完全使用Storyboard。 - Dennis
嗯,我知道我可以通过代码来完成这些事情,但现在我更新了问题,真正想要做的事情可能我表达得不够清楚。 - Massimo Polimeni
非常感谢!我对各种解决方案都有疑虑,但现在一切都清楚了 :) 我正在评估第三个解决方案,使用属性并根据其值执行操作。再次感谢您的时间! - Massimo Polimeni
@MassimoPolimeni,您能在这里发布您的第三个解决方案吗? - saurabh

2
您无法将父类转换为子类,因为父类没有能力了解子类正在做什么。但是,您可以从子类转换为父类,因此您需要将您的视图控制器设置为GrowingEffect,然后将其转换为Effect。但是,这样做也没有什么优点,除非某个方法需要父类并且您正在使用子类。看起来您需要重新设计您想要的视图控制器布局。现在我假设您有两个子类,称为GrowingEffect和ShrinkingEffect。在设计师中,您将1设置为GrowingEffect,另一个设置为ShrinkingEffect,并确保它们具有唯一的标识符。然后,您可以使用您的视图来呈现Effect,并传入其中任何一个对象。

好的,我知道这个解决方案,但我需要在 Interface Builder 中设置 2 个视图控制器...是否有一种方法可以在 IB 中使用一个父类和多个子类以及一个视图控制器的解决方案? - Massimo Polimeni
你可以将故事板中的视图控制器设置为父视图控制器,然后当呈现视图控制器时,从故事板中获取父视图控制器,然后基于父视图控制器创建一个新的子对象,并呈现该视图。 let childvc = GlowingEffect(viewController: vc) currentViewController.presentViewController(childvc, animated:true, completion:nil);``` 当然,您需要实现NSCoding方法来创建复制。 - Knight0fDragon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接