简体   繁体   English

如何向下浇铸UIViewController Swift

[英]how to DownCasting UIViewController Swift

base ViewController 基本ViewController

import UIKit

class SubViewPost: UIViewController {

    @IBOutlet weak var content: UILabel!

    @IBOutlet weak var recommendCount: UILabel!
    @IBOutlet weak var recommendButton: UIButton!

    var postInfo:PostInfo!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

child ViewController 子ViewController

import UIKit

class SubViewOne: SubViewPost {

    @IBAction func likeWorry(_ sender: Any) {
        Option.recommend(postInfo: postInfo, mRecommendCount: recommendCount, mRecommendButton: recommendButton)

    }



}

and another child viewController 和另一个子viewController

import UIKit

class SubViewTwo: SubViewPost {

    override func viewDidLoad() {
        recommendCount.alpha=0
        recommendButton.alpha=0
    }


}

i want add subviewOne or SubViewTwo 我想添加subviewOne或SubViewTwo

My ParentView 我的父母

var subViewPost:SubViewPost

 if postType == 1{
 subViewPost = storyboard?.instantiateViewController(withIdentifier: "SubViewPost") as! SubViewOne
 }else{
subViewPost = storyboard?.instantiateViewController(withIdentifier: "SubViewPost") as! SubViewTwo
 }

 containerView.addSubview(subViewPost.view)

raise error 引发错误

Could not cast value of type 
'MyApp.SubViewPost' (0x101151728) to 'MyApp.SubViewOne' (0x10114d9d0).

2018-07-10 14:40:56.007436+0900 MyApp[7207:209932] 
Could not cast value of type 'MyApp.SubViewPost' (0x101151728) to 'MyApp.SubViewOne' (0x10114d9d0).

how to chagne view controller by According to postType 如何根据postType更改视图控制器

SubView One have Recommned 推荐使用SubView

but SubView Two haven't Recommend 但是SubView 2不推荐

SubView 1,2 have same UI SubView 1,2具有相同的UI

The error message is clear. 错误消息是明确的。 When you say 当你说

storyboard?.instantiateViewController(withIdentifier: "SubViewPost")

what you get from the storyboard is a view controller whose class is SubViewPost. 从情节提要中获得的是一个视图控制器,其类为SubViewPost。 You cannot wave a magic casting wand and claim that it is a SubViewOne instead; 您不能挥舞着魔术棒,而是声称它是SubViewOne; it isn't. 不是。

If you wanted this view controller to be a SubViewOne, then you should have declared it as a SubViewOne in the storyboard in the Identity inspector. 如果希望此视图控制器为SubViewOne,则应在身份检查器的情节提要中将其声明为SubViewOne。


I think I see what you are trying to do, and why you are confused about why you can't do it this way. 我想我知道您要尝试做的事情,以及为什么对为什么不能这样做感到困惑。

What's in the storyboard is an instance , not a class. 故事板上的内容是实例 ,而不是类。 Yes, it is an instance of some class, but it is an instance of that class. 是的,它是某个类的实例,但它是该类的实例。 So when you design the interface in the storyboard, you are designing the interface associated with that one instance of that one class. 因此,在情节提要中设计界面时,您正在设计该类的一个实例相关联的界面。

If your goal is to have a single interface associated with multiple classes , the interface must be generated in code or loaded from a View .xib file — not designed in a storyboard. 如果您的目标是使一个具有与多个类相关联的接口,则该接口必须以代码生成或从View .xib文件加载(而不是在情节提要中设计)。


However, you would be better off not trying to use subclassing in this situation in the first place. 但是,最好不要在这种情况下首先尝试使用子类化。 What I do in a similar situation is give my view controller an enum property that says which "kind" of view controller it is, and obey accordingly in code. 在类似情况下,我要做的是为我的视图控制器提供一个枚举属性,该属性说明它是哪种类型的视图控制器,并相应地遵循代码。 That a way, a single class serves multiple purposes. 这样一来,一个类就可以达到多种目的。

The UViewController class for your scene "SubViewPost" in your storyboard is set to SubViewPost and that is what instantiateViewController will be returning. UViewController在你的故事板类场景“SubViewPost”设置为SubViewPost ,这就是instantiateViewController将重返。 You cannot downcast an instance of SubViewPost to SubViewOne or SubViewTwo . 您不能将SubViewOne的实例下SubViewPost SubViewOneSubViewTwo

You could define two identical scenes in your storyboard, each with the appropriate view controller class, but that would require a lot of duplication. 您可以在情节提要中定义两个相同的场景,每个场景都具有适当的视图控制器类,但这将需要大量重复。

Since the only difference is the visibility of the recommendButton and recommendCount elements, why not just handle that via a property: 由于唯一的区别是recommendButtonrecommendCount元素的可见性,为什么不仅仅通过属性来处理它:

var subViewPost = storyboard?.instantiateViewController(withIdentifier: "SubViewPost") as! SubViewPost

subViewPost.recommendVisible = (postType == 1)

SubViewPost.swift SubViewPost.swift

var recommendVisible = true 

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    recommendCount.isHidden = !recommendVisible
    recommendButton.isHidden = !recommendVisible
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM